如何在Java对象列表中搜索
我有一个对象列表,列表非常大。 对象是
class Sample { String value1; String value2; String value3; String value4; String value5; }
现在我必须在列表中搜索对象的特定值。 假设value3=='three'
我必须返回那些对象(我的搜索并不总是基于value3)
清单是
List list = new ArrayList();
这样做的有效方法是什么?
谢谢。
您可以试试Apache Commons Collections 。
有一个CollectionUtils类,允许您通过自定义谓词选择或过滤项目。
你的代码是这样的:
Predicate condition = new Predicate() { boolean evaluate(Object sample) { return ((Sample)sample).value3.equals("three"); } }; List result = CollectionUtils.select( list, condition );
更新:
在java8中 ,使用Lambdas和StreamAPI应该是:
List result = list.stream() .filter(item -> item.value3.equals("three")) .collect(Collectors.toList());
好多了!
使用Java 8
使用Java 8,您只需将列表转换为流即可编写:
import java.util.List; import java.util.stream.Collectors; List list = new ArrayList (); List result = list.stream() .filter(a -> Objects.equals(a.value3, "three")) .collect(Collectors.toList());
注意
-
a -> Objects.equals(a.value3, "three")
是一个lambda表达式 -
result
是一个带有Sample
类型的List
- 它非常快,每次迭代都没有演员
- 如果你的filter逻辑变得更重,你可以做
list.parallelStream()
而不是list.stream()
( 读这个 )
Apache Commons
如果您不能使用Java 8,您可以使用Apache Commons库并编写:
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.Predicate; Collection result = CollectionUtils.select(list, new Predicate() { public boolean evaluate(Object a) { return Objects.equals(((Sample) a).value3, "three"); } }); // If you need the results as a typed array: Sample[] resultTyped = (Sample[]) result.toArray(new Sample[result.size()]);
注意:
- 每次迭代都有一个从
Object
到Sample
的强制转换 - 如果您需要将结果输入为
Sample[]
,则需要额外的代码(如我的示例所示)
奖金:一篇很好的博客文章,讨论如何在列表中找到元素。
如果您始终基于value3
搜索,则可以将对象存储在Map中:
Map> map = new HashMap <>();
然后,您可以使用key = value3
和value =具有相同value3
属性的Sample对象列表填充地图。
然后,您可以查询地图:
List allSamplesWhereValue3IsDog = map.get("Dog");
注意:如果没有2个Sample
实例可以具有相同的value3
,则可以使用Map
。
我修改了这个列表,并为样本添加了一个List试试这个
伪代码
Sample { List values; List getList() { return values} } for(Sample s : list) { if(s.getString.getList.contains("three") { return s; } }
由于您的列表是ArrayList
,因此可以假定它是未排序的。 因此,无法搜索比O(n)更快的元素。
如果可以,您应该考虑将列表更改为Set
(使用HashSet
作为实现),并为您的示例类使用特定的Comparator
。
另一种可能性是使用HashMap
。 您可以将数据添加为Sample
(请使用大写字母启动类名称)并使用要搜索的字符串作为键。 然后你可以简单地使用
Sample samp = myMap.get(myKey);
如果每个键可以有多个样本,请使用Map
,否则使用Map
。 如果使用多个键,则必须创建包含相同数据集的多个映射。 因为它们都指向相同的对象,所以空间应该不是那么大的问题。