从列表中遍历和查找对象字段的最佳方法

时间:2016-10-21 10:46:37

标签: java list equals

我有一个Custom对象列表,我希望通过给定Id(自定义对象中的字段)来查找对象。我正在为此编码,所以我在比较字段时找到了两个解决方案。

1

private Product getProduct(String productId,List<Product> productList){
        for (int i = 0; i < productList.size(); i++) {
            if (productId.equals(productList.get(i).getId())) {
                return productList.get(i);
            }


        }
        return null;
    }

2

 private Product getProduct(String productId,List<Product> productList){
        for (int i = 0; i < productList.size(); i++) {
            if (productList.get(i).getId().equals(productId)) {
                return productList.get(i);
            }
        }
        return null;
    }

差异在if条件下,我想知道哪一个比另一个好,为什么,何时使用第一种方法以及何时使用第二种方法?

4 个答案:

答案 0 :(得分:2)

由于Java equals()required 对称,因此两个代码段之间没有区别。

两个片段都是次优的,因为它们通过数字索引进行迭代,并在返回之前检索productList.get(i)两次。按索引进行迭代尤其危险,因为传递LinkedList<Product>会大大减慢搜索速度。

更好的方法是使用for-each形式的循环:

for (Product p : productList) {
    if (p.getId().equals(productId)) {
        return p;
    }
}
return null;

答案 1 :(得分:2)

您的两个实现中的关注点是可以在空值上调用.equals。

如果你能保证它们都不为null,那么它们是等价的。

如果您使用的是Java 8,那么流可能是更好的选择。

private Product getProduct(String productId,List<Product> productList){
    return products.stream()
        .filter(p-> productId.equals(p.getId())
        .findFirst()
        .orElse(null);

答案 2 :(得分:0)

第一个在参数equals上调用productId,而第二个在equals的当前列表元素上调用productList。结果相同,因为equals 对称

  

对于任何非空引用值xy,当{且仅x.equals(y)返回true时,y.equals(x)应返回true。

您也可以使用流,因此您不必关心实现细节(此外,Objects#equals(Object, Object)是空的安全):

String p = productList.stream().filter(e -> Objects.equals(e, productId))
                               .findFirst()
                               .orElse(null);

查看this问题以获取更多信息。

答案 3 :(得分:0)

当您确定产品ID永远不会为空时,它并不重要。

但总的来说,以防守方式编程总是好的,所以例如更喜欢使用

"SomeString".equals(aString)

而不是

aString.equals("SomeString")

因为你知道“SomeString”永远不会是null

或使用

Objects.equals(object1, object2)

当两个对象都可能是null时。