如何在 Java 对象列表中搜索

问题描述 投票:0回答:7

我有一个对象列表,并且列表非常大。对象是

class Sample {
    String value1;
    String value2;
    String value3;
    String value4;
    String value5;
 }

现在我必须在列表中搜索对象的特定值。假设

value3=='three'
我必须返回这些对象(我的搜索并不总是基于 value3)

名单是

List<Sample> list = new ArrayList<Sample>();

有效的方法是什么?

java list search collections
7个回答
67
投票

您可以尝试一下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());

好多了!


53
投票

使用Java 8

使用 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[]
    ,则需要额外的代码(如我的示例中所示)



奖励:一篇不错的博客文章谈论如何在列表中查找元素。


5
投票

如果您总是基于

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>


3
投票

我修改此列表并向示例添加一个列表,试试这个

伪代码

Sample {
   List<String> values;
   List<String> getList() {
   return values}
}



for(Sample s : list) {
   if(s.getString.getList.contains("three") {
      return s;
   }
}

0
投票

由于您的列表是

ArrayList
,因此可以假设它未排序。因此,没有办法搜索比 O(n) 更快的元素。

如果可以的话,您应该考虑将您的列表更改为

Set
(以
HashSet
作为实现),并为您的示例类指定特定的
Comparator

另一种可能性是使用

HashMap
。您可以将数据添加为
Sample
(请以大写字母开头类名称)并使用要搜索的字符串作为键。然后你就可以简单地使用

Sample samp = myMap.get(myKey);

如果每个键可以有多个样本,请使用

Map<String, List<Sample>>
,否则使用
Map<String, Sample>
如果您使用多个键,则必须创建多个包含相同数据集的映射。由于它们都指向相同的对象,因此空间不应该成为太大的问题。


0
投票

您可以过滤列表:

list.stream().filter(
              sample -> sample.getValue4().equals("4")
              ).forEach(System.out::println)

0
投票

我建议for+if。

Object result; 
for (Object o: objects){ 
  if (o.value3.equals("three")){ 
    result=o; 
    break;
  }
}

没有溪流,没有番石榴,我觉得很简单。

© www.soinside.com 2019 - 2024. All rights reserved.