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

Jee*_*evi 26 java collections search list

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

class Sample {
    String value1;
    String value2;
    String value3;
    String value4;
    String value5;
 }
Run Code Online (Sandbox Code Playgroud)

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

名单是

List<Sample> list = new ArrayList<Sample>();
Run Code Online (Sandbox Code Playgroud)

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

谢谢.

Est*_*eve 43

您可以尝试Apache Commons Collections.

有一个CollectionUtils类,允许您通过自定义谓词选择或过滤项目.

你的代码是这样的:

Predicate condition = new Predicate() {
   boolean evaluate(Object sample) {
        return ((Sample)sample).value3.equals("three");
   }
};
List result = CollectionUtils.select( list, condition );
Run Code Online (Sandbox Code Playgroud)

更新:

java8中,使用LambdasStreamAPI应该是:

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

好多了!


Yve*_* M. 40

使用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());
Run Code Online (Sandbox Code Playgroud)

注意

  • a -> Objects.equals(a.value3, "three")是一个lambda表达式
  • resultList一种Sample类型
  • 它非常快,每次迭代都没有演员
  • 如果您的过滤器逻辑变得更重,您可以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()]);
Run Code Online (Sandbox Code Playgroud)

注意:

  • 有从铸造ObjectSample在每次迭代
  • 如果您需要输入结果Sample[],则需要额外的代码(如我的示例所示)



奖金:一篇很好的博客文章,讨论如何在列表中找到元素.

  • http://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java (2认同)
  • 那么`a.value3.equals("three")`会看起来更自然,但你的方式也是"无效的",所以请保持:D.感谢您的更新,但我仍然想知道为什么没有人注意到它.因为你更喜欢其他语言(根据你的标签)我不能/不会责怪你,因为字符串比较可能在那里有所不同.但是没关系,现在已经修好了. (2认同)

ass*_*ias 5

如果您始终基于 进行搜索value3,则可以将对象存储在 Map 中:

Map<String, List<Sample>> map = new HashMap <>();
Run Code Online (Sandbox Code Playgroud)

key = value3然后,您可以使用value = 具有相同属性的 Sample 对象列表来填充映射value3

然后您可以查询地图:

List<Sample> allSamplesWhereValue3IsDog = map.get("Dog");
Run Code Online (Sandbox Code Playgroud)

注意:如果没有两个Sample实例可以具有相同的value3,您可以简单地使用Map<String, Sample>.

  • 不..我的搜索并不总是基于 value3..它可以基于对象中的任何字段 (2认同)