从列表中遍历和查找对象字段的最佳方法
Best way to traverse and find an object field from a list
我有一个自定义对象列表,我想通过给定的 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
条件,我想知道哪个比另一个更好,为什么,什么时候使用第一种方法,什么时候使用第二种方法?
第一个在参数 productId
上调用 equals
,而第二个在 productList
中的当前列表元素上调用 equals
。结果是一样的,因为 equals
是 对称的 :
for any non-null reference values x
and y
, x.equals(y)
should return true if and only if y.equals(x)
returns true.
您也可以为此使用流,因此您不必关心实现细节(此外,Objects#equals(Object, Object)
是空安全的):
String p = productList.stream().filter(e -> Objects.equals(e, productId))
.findFirst()
.orElse(null);
查看 this 问题以获取更多信息。
由于 equals()
被 Java required 对称,所以这两个片段之间没有区别。
这两个片段都不是最佳的,因为它们按数字索引迭代,并在返回之前检索 productList.get(i)
两次。按索引迭代特别危险,因为传递 LinkedList<Product>
会大大减慢您的搜索速度。
更好的方法是使用 for-each 形式的循环:
for (Product p : productList) {
if (p.getId().equals(productId)) {
return p;
}
}
return null;
当您确定产品 ID 永远不会为空时,这并不重要。
但总的来说,以防御方式编程总是好的,所以例如更喜欢使用
"SomeString".equals(aString)
而不是
aString.equals("SomeString")
因为你知道 "SomeString" 永远不会是 null
。
或使用
Objects.equals(object1, object2)
当两个对象都可能是 null
。
您的两个实现中的问题是对空值调用 .equals 的可能性。
如果你能保证它们都不为空那么它们是等价的。
如果您使用的是 Java 8,stream 可能是更好的选择。
private Product getProduct(String productId,List<Product> productList){
return products.stream()
.filter(p-> productId.equals(p.getId())
.findFirst()
.orElse(null);
我有一个自定义对象列表,我想通过给定的 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
条件,我想知道哪个比另一个更好,为什么,什么时候使用第一种方法,什么时候使用第二种方法?
第一个在参数 productId
上调用 equals
,而第二个在 productList
中的当前列表元素上调用 equals
。结果是一样的,因为 equals
是 对称的 :
for any non-null reference values
x
andy
,x.equals(y)
should return true if and only ify.equals(x)
returns true.
您也可以为此使用流,因此您不必关心实现细节(此外,Objects#equals(Object, Object)
是空安全的):
String p = productList.stream().filter(e -> Objects.equals(e, productId))
.findFirst()
.orElse(null);
查看 this 问题以获取更多信息。
由于 equals()
被 Java required 对称,所以这两个片段之间没有区别。
这两个片段都不是最佳的,因为它们按数字索引迭代,并在返回之前检索 productList.get(i)
两次。按索引迭代特别危险,因为传递 LinkedList<Product>
会大大减慢您的搜索速度。
更好的方法是使用 for-each 形式的循环:
for (Product p : productList) {
if (p.getId().equals(productId)) {
return p;
}
}
return null;
当您确定产品 ID 永远不会为空时,这并不重要。
但总的来说,以防御方式编程总是好的,所以例如更喜欢使用
"SomeString".equals(aString)
而不是
aString.equals("SomeString")
因为你知道 "SomeString" 永远不会是 null
。
或使用
Objects.equals(object1, object2)
当两个对象都可能是 null
。
您的两个实现中的问题是对空值调用 .equals 的可能性。
如果你能保证它们都不为空那么它们是等价的。
如果您使用的是 Java 8,stream 可能是更好的选择。
private Product getProduct(String productId,List<Product> productList){
return products.stream()
.filter(p-> productId.equals(p.getId())
.findFirst()
.orElse(null);