如何在Java对象列表中搜索

如何在Java对象列表中搜索,java,list,search,collections,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&g

我有一个物品清单,清单很大。对象是

class Sample {
    String value1;
    String value2;
    String value3;
    String value4;
    String value5;
 }
现在我必须在列表中搜索对象的特定值。如果
value3=='three'
我必须返回这些对象(我的搜索并不总是基于value3)

名单是

List<Sample> list = new ArrayList<Sample>();
List List=new ArrayList();
做这件事的有效方法是什么


谢谢。

如果您总是基于
值3
进行搜索,您可以将对象存储在地图中:

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

注意:如果没有2个
示例
实例可以具有相同的
值3
,您可以简单地使用
映射

修改此列表并将列表添加到示例中尝试此操作

伪码

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



for(Sample s : list) {
   if(s.getString.getList.contains("three") {
      return s;
   }
}
示例{
列表值;
List getList(){
返回值}
}
对于(示例s:列表){
if(s.getString.getList.contains(“三”){
返回s;
}
}

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

如果可以,您应该考虑将列表更改为一个
集合
(以
哈希集
作为实现),并为示例类指定一个
比较器

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

Sample samp = myMap.get(myKey);
如果每个键可以有多个样本,请使用
Map
,否则请使用
Map
如果使用多个键,则必须创建包含相同数据集的多个贴图。因为它们都指向相同的对象,所以空间应该不会有太大问题。

您可以尝试一下

有一个类允许您按自定义方式选择或筛选项目

您的代码如下所示:

Predicate condition = new Predicate() {
   boolean evaluate(Object sample) {
        return ((Sample)sample).value3.equals("three");
   }
};
List result = CollectionUtils.select( list, condition );
更新:

java8中,使用Lambdas,应该是:

List<Sample> result = list.stream()
     .filter(item -> item.value3.equals("three"))
     .collect(Collectors.toList());
List result=List.stream()
.filter(item->item.value3.equals(“三”))
.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());
请注意:

  • 在每次迭代中都有一个从
    对象
    示例
    的转换
  • 如果需要将结果键入为
    Sample[]
    ,则需要额外的代码(如我的示例所示)



奖励:讨论如何在列表中查找元素。

您自己尝试过什么吗?为什么不创建列表?()他说他有一个对象列表。@ TikoDoMMA,我想他是一个代码>清单[/COD],这是一个LISTiF,你在寻找很多对象的效率,我会考虑排序对象的层次结构,然后是一个有效的算法来跳过不可能的事物。不。我的搜索并不总是基于价值3。它可以基于任何FIEL。介入object@Sun这是性能和内存足迹之间的折衷:每个字段维护一个映射会更快,但会使用更多内存,每次需要搜索时循环列表会更慢,但会使用更少内存。或者,如果对象的结构是平面的(仅字符串字段)你可以看看Guava的表格-我从来没有用过它。我的列表非常大。我正在寻找一个有效的搜索。这是唯一可能的方法吗?你可以将值组织成一个哈希图,以避免检查样本中的每个条目…不知怎的,令人遗憾的是,在大多数情况下,一个没有完成给定任务的答案得到了13票。请重新思考我们应该比较字符串。@Tom到底什么地方出了问题?@Toms谢谢:)Aswer已经进行了相应的编辑。Well
a.value3.equals(“三”)
看起来更自然,但您的方式也是“空安全”的,所以请记住:D.谢谢您的更新,但我仍然想知道为什么没有人注意到它。因为你更喜欢其他语言(根据你的标签),我不能/不会责怪你,因为字符串比较在那里可能会有不同的工作方式。但是无论如何,它现在是固定的。@Tom“three”。equals((Sample)a).value3)也可以工作,并且是“空安全的”。CollectionUtils方法给了我这个错误:
java.lang.NoSuchMethodError:No接口方法stream()Ljava/util/stream/stream;在类Ljava/util/List中;或者它的超类(声明'java.util.List'出现在/system/framework/core libart.jar
中,我不能使用Lambdas,因为Android SDK不支持java 8。@Yankee也遇到了同样的问题。你成功了吗?@ono我使用了java 8方法,效果很好。但是请记住,你必须在Gradle中添加一些java 8特定的依赖项file@Yankee我没有他导入了gradle,但我仍然能得到它。你有这两个对吗?
编译选项{sourceCompatibility JavaVersion.VERSION\u 1\u 8 targetCompatibility JavaVersion.VERSION\u 1\u 8}
@ono是的。它们在我的build.gradle(模块:app)中,在我的build.gradle(项目)中有
类路径'me.tatarka:gradle retrolambda:3.4.0'
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());
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()]);