我有一个对象列表,并且列表非常大。对象是
class Sample {
String value1;
String value2;
String value3;
String value4;
String value5;
}
现在我必须在列表中搜索对象的特定值。假设
value3=='three'
我必须返回这些对象(我的搜索并不总是基于 value3)
名单是
List<Sample> list = new ArrayList<Sample>();
有效的方法是什么?
您可以尝试一下Apache Commons Collections。
有一个类 CollectionUtils 允许您通过自定义 Predicate 选择或过滤项目。
你的代码将是这样的:
Predicate condition = new Predicate() {
boolean evaluate(Object sample) {
return ((Sample)sample).value3.equals("three");
}
};
List result = CollectionUtils.select( list, condition );
更新:
在 java8 中,使用 Lambda 和 StreamAPI 这应该是:
List<Sample> result = list.stream()
.filter(item -> item.value3.equals("three"))
.collect(Collectors.toList());
好多了!
使用 Java 8,您可以简单地将列表转换为 流,从而允许您编写:
import java.util.List;
import java.util.stream.Collectors;
List<Sample> list = new ArrayList<Sample>();
List<Sample> result = list.stream()
.filter(a -> Objects.equals(a.value3, "three"))
.collect(Collectors.toList());
请注意
a -> Objects.equals(a.value3, "three")
是一个 lambda 表达式result
是具有 List
类型的
Sample
list.parallelStream()
而不是 list.stream()
(阅读本文)如果你不能使用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<String, List<Sample>> map = new HashMap <>();
然后,您可以使用
key = value3
填充地图,并且 value = 具有相同 value3
属性的示例对象列表。
您可以查询地图:
List<Sample> allSamplesWhereValue3IsDog = map.get("Dog");
注意:如果没有 2 个
Sample
实例可以具有相同的 value3
,您可以简单地使用 Map<String, Sample>
。
我修改此列表并向示例添加一个列表,试试这个
伪代码
Sample {
List<String> values;
List<String> 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<String, List<Sample>>
,否则使用 Map<String, Sample>
。 如果您使用多个键,则必须创建多个包含相同数据集的映射。由于它们都指向相同的对象,因此空间不应该成为太大的问题。
您可以过滤列表:
list.stream().filter(
sample -> sample.getValue4().equals("4")
).forEach(System.out::println)
我建议for+if。
Object result;
for (Object o: objects){
if (o.value3.equals("three")){
result=o;
break;
}
}
没有溪流,没有番石榴,我觉得很简单。