如何在Java对象列表中进行搜索

时间:2012-10-30 12:28:08

标签: java list search collections

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

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

现在我必须在列表中搜索对象的特定值。假设value3=='three'我必须返回这些对象(我的搜索并不总是基于value3)

列表是

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

这样做的有效方法是什么?

感谢。

5 个答案:

答案 0 :(得分:40)

您可以尝试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 中,使用Lambdas和StreamAPI这应该是:

List<Sample> result = list.stream()
     .filter(item -> item.value3.equals("three"))
     .collect(Collectors.toList());

好多了!

答案 1 :(得分:39)

使用Java 8

使用Java 8,您只需将列表转换为stream,即可编写:

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 expression
  • result是具有List类型
  • Sample
  • 它非常快,每次迭代都没有演员
  • 如果您的过滤器逻辑变重,您可以执行list.parallelStream()而不是list.stream()read this


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()]);

请注意:

  • 每次迭代都有ObjectSample的演员
  • 如果您需要将结果输入为Sample[],则需要额外的代码(如我的示例所示)



Bonus:nice blog article谈论如何在列表中找到元素。

答案 2 :(得分:3)

如果您始终根据value3进行搜索,则可以将对象存储在地图中:

Map<String, List<Sample>> map = new HashMap <>();

然后,您可以使用key = value3和value =具有相同value3属性的Sample对象列表填充地图。

然后您可以查询地图:

List<Sample> allSamplesWhereValue3IsDog = map.get("Dog");

注意:如果没有2 Sample个实例可以使用相同的value3,则只需使用Map<String, Sample>

答案 3 :(得分:3)

我修改了这个列表并向样本中添加了一个列表试试这个

伪代码

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



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

答案 4 :(得分:0)

由于您的列表是ArrayList,因此可以假定它是未排序的。因此,无法搜索比 O(n)更快的元素。

如果可以,您应该考虑将您的列表更改为Set(使用HashSet作为实现),并为您的示例类设置特定的Comparator

另一种可能性是使用HashMap。您可以将数据添加为Sample(请使用大写字母启动类名称)并使用要搜索的字符串作为键。然后你可以简单地使用

Sample samp = myMap.get(myKey);

如果每个密钥可以有多个样本,请使用Map<String, List<Sample>>,否则使用Map<String, Sample>如果使用多个键,则必须创建多个包含相同数据集的地图。由于它们都指向相同的对象,因此空间不应该是一个大问题。