在 java ArrayList 中搜索

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/985229/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 21:53:15  来源:igfitidea点击:

search in java ArrayList

javasearcharraylist

提问by fenec

I'm trying to figure out the best way to search a customer in an ArrayListby its Id number. The code below is not working; the compiler tells me that I am missing a returnstatement.

我正在尝试找出ArrayList通过 ID 号搜索客户的最佳方式。下面的代码不起作用;编译器告诉我我缺少一个return语句。

Customer findCustomerByid(int id){
    boolean exist=false;

    if(this.customers.isEmpty()) {
        return null;
    }

    for(int i=0;i<this.customers.size();i++) {
        if(this.customers.get(i).getId() == id) {
            exist=true;
            break;
        }

        if(exist) {
            return this.customers.get(id);
        } else {
            return this.customers.get(id);
        }
    }

}

//the customer class is something like that
public class Customer {
    //attributes
    int id;
    int tel;
    String fname;
    String lname;
    String resgistrationDate;
}

采纳答案by Brandon E Taylor

The compiler is complaining because you currently have the 'if(exist)' block inside of your for loop. It needs to be outside of it.

编译器正在抱怨,因为您目前在 for 循环中有 'if(exist)' 块。它需要在它之外。

for(int i=0;i<this.customers.size();i++){
        if(this.customers.get(i).getId() == id){
            exist=true;
            break;
        }
}

if(exist) {
    return this.customers.get(id);
} else {
    return this.customers.get(id);
}

That being said, there are better ways to perform this search. Personally, if I were using an ArrayList, my solution would look like the one that Jon Skeet has posted.

话虽如此,有更好的方法来执行此搜索。就个人而言,如果我使用的是 ArrayList,我的解决方案将类似于 Jon Skeet 发布的解决方案。

回答by Lucero

Customer findCustomerByid(int id){
    for (int i=0; i<this.customers.size(); i++) {
        Customer customer = this.customers.get(i);
        if (customer.getId() == id){
             return customer;
        }
    }
    return null; // no Customer found with this ID; maybe throw an exception
}

回答by Will Hartung

You're missing the return statement because if your list size is 0, the for loop will never execute, thus the if will never run, and thus you will never return.

您缺少 return 语句,因为如果您的列表大小为 0,则 for 循环将永远不会执行,因此 if 永远不会运行,因此您永远不会返回。

Move the if statement out of the loop.

将 if 语句移出循环。

回答by Jon Skeet

Others have pointed out the error in your existing code, but I'd like to take two steps further. Firstly, assuming you're using Java 1.5+, you can achieve greater readability using the enhanced for loop:

其他人已经指出了您现有代码中的错误,但我想更进两步。首先,假设您使用的是 Java 1.5+,您可以使用增强的 for 循环实现更高的可读性:

Customer findCustomerByid(int id){    
    for (Customer customer : customers) {
        if (customer.getId() == id) {
            return customer;
        }
    }
    return null; 
}

This has also removed the micro-optimisation of returning nullbefore looping - I doubt that you'll get any benefit from it, and it's more code. Likewise I've removed the existsflag: returning as soon as you know the answer makes the code simpler.

这也消除了null循环前返回的微优化- 我怀疑您是否会从中受益,而且代码更多。同样,我删除了exists标志:一旦您知道答案就返回使代码更简单。

Note that in your original code I thinkyou had a bug. Having found that the customer at index ihad the right ID, you then returned the customer at index id- I doubt that this is really what you intended.

请注意,在您的原始代码中,我认为您有一个错误。发现 index 处的客户i具有正确的 ID,然后您返回了 index 处的客户id- 我怀疑这是否真的是您的意图。

Secondly, if you're going to do a lot of lookups by ID, have you considered putting your customers into a Map<Integer, Customer>?

其次,如果您要通过 ID 进行大量查找,您是否考虑过将客户放入Map<Integer, Customer>?

回答by Dan Gravell

Personally I rarely write loops myself now when I can get away with it... I use the Jakarta commons libs:

就我个人而言,当我可以逃脱时,我现在很少自己编写循环......我使用 Jakarta commons libs:

Customer findCustomerByid(final int id){
    return (Customer) CollectionUtils.find(customers, new Predicate() {
        public boolean evaluate(Object arg0) {
            return ((Customer) arg0).getId()==id;
        }
    });
}

Yay! I saved one line!

好极了!我保存了一行!

回答by Markus

Even if that topic is quite old, I'd like to add something. If you overwrite equalsfor you classes, so it compares your getId, you can use:

即使这个话题已经很老了,我还是想补充一点。如果你equals为你的类覆盖,所以它比较你的getId,你可以使用:

customer = new Customer(id);
customers.get(customers.indexOf(customer));

Of course, you'd have to check for an IndexOutOfBounds-Exception, which oculd be translated into a null pointer or a custom CustomerNotFoundException.

当然,您必须检查IndexOutOfBounds-Exception,它可能会被转换为空指针或自定义CustomerNotFoundException.

回答by Alan Sorrill

I did something close to that, the compiler is seeing that your return statement is in an If() statement. If you wish to resolve this error, simply create a new local variable called customerId before the If statement, then assign a value inside of the if statement. After the if statement, call your return statement, and return cstomerId. Like this:

我做了一些接近于此的事情,编译器看到您的 return 语句在 If() 语句中。如果您希望解决此错误,只需在 If 语句之前创建一个名为 customerId 的新局部变量,然后在 if 语句内赋值。在 if 语句之后,调用您的 return 语句,并返回 cstomerId。像这样:

Customer findCustomerByid(int id)
{
    boolean exist=false;

    if(this.customers.isEmpty()) {
        return null;
    }

    for(int i=0;i<this.customers.size();i++) {
        if(this.customers.get(i).getId() == id) {
            exist=true;
            break;
        }

        int customerId;

        if(exist) {
            customerId = this.customers.get(id);
        } else {
            customerId = this.customers.get(id);
        }
    }
    return customerId;
}

回答by cbag

In Java 8:

在 Java 8 中:

Customer findCustomerByid(int id) {
    return this.customers.stream()
        .filter(customer -> customer.getId().equals(id))
        .findFirst().get();
}

It might also be better to change the return type to Optional<Customer>.

将返回类型更改为Optional<Customer>.