2009-06-12 85 views
15

我试图找出通过其Id编号搜索ArrayList中的客户的最佳方法。下面的代码不起作用;编译器告诉我,我错过了return声明。在java中搜索ArrayList

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; 
} 
+12

其中一个主要的Java良好实践是总是使用大括号,即使该块只有一个句子,以避免类似于你的问题 – 2009-06-12 06:24:01

回答

16

编译器抱怨,因为你目前在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); 
} 

这就是说,有更好的方法来执行此搜索。就个人而言,如果我使用ArrayList,我的解决方案看起来就像Jon Skeet发布的解决方案。

+0

是的,我对其进行了重新格式化,现在更明显 – 2009-06-12 06:19:35

+0

我强烈怀疑代码仍然破碎(注意在customers.get最后的参数)。这两个分支都有相同代码的“if/else”事实也是非常可疑的! – 2009-06-12 06:32:12

+0

我同意,Jon。此外,还有更好的方法来进行搜索(就像其他海报所指出的那样)。 – 2009-06-12 06:35:41

10
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 
} 
2

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

将if语句移出循环。

48

其他人已经指出了你现有的代码中的错误,但我想进一步采取两个步骤。首先,假设你使用Java 1.5+,您可以使用取得更大的可读性增强的for循环

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

这也去掉循环之前返回null的微型优化 - 我怀疑你”我们可以从中获得任何好处,而且它是更多的代码。同样,我已经删除了exists标志:只要您知道答案使代码更简单,就会返回。

请注意,在您的原始代码我认为你有一个错误。在发现指数为i的顾客拥有正确的身份证明后,您就以id索引返回了顾客 - 我怀疑这确实是你的意图。其次,如果你打算通过ID做很多查询,你有没有考虑过把你的客户放到Map<Integer, Customer>

16

个人而言,我很少写自己的循环现在,当我可以逃脱它...我用的Jakarta Commons库:

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

耶!我保存了一行!

2

即使该主题相当老,我想添加一些东西。 如果覆盖equals为你的类,所以它会比较您getId,你可以使用:

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

当然,你必须检查的IndexOutOfBounds -Exception,这oculd被转换成一个空指针或自定义CustomerNotFoundException

0

我做了一些与之相近的事情,编译器看到你的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;

}

1

在Java 8:

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

它也可能会更好的返回类型更改为Optional<Customer>