我有一个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
条件下,我想知道哪一个比另一个好,为什么,何时使用第一种方法以及何时使用第二种方法?
答案 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
对称:
对于任何非空引用值
x
和y
,当{且仅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
时。