我想检查一个列表是否包含一个对象,该对象具有具有特定值的字段。现在,我可以使用循环来遍历和检查,但我很好奇是否有更高效的代码。

类似的;

if(list.contains(new Object().setName("John"))){
    //Do some stuff
}

我知道上面的代码没有做任何事情,它只是粗略地演示了我想要实现的目标。

另外,澄清一下,我不想使用简单循环的原因是,这段代码将进入一个循环,这个循环在一个循环中,而这个循环又在一个循环中。为了可读性,我不想一直在这些循环中添加循环。所以我想知道是否有什么简单的替代方案。


当前回答

尽管JAVA 8 SDK有很多收集工具库可以帮助你工作,例如: http://commons.apache.org/proper/commons-collections/

Predicate condition = new Predicate() {
   boolean evaluate(Object obj) {
        return ((Sample)obj).myField.equals("myVal");
   }
};
List result = CollectionUtils.select( list, condition );

其他回答

谷歌番石榴

如果您正在使用Guava,您可以采用功能方法并执行以下操作

FluentIterable.from(list).find(new Predicate<MyObject>() {
   public boolean apply(MyObject input) {
      return "John".equals(input.getName());
   }
}).Any();

看起来有点啰嗦。但是谓词是一个对象,您可以为不同的搜索提供不同的变体。注意库本身是如何分离集合的迭代和希望应用的函数的。您不必为特定的行为重写equals()。

如下面所述,Java 8及以后版本中内置的Java .util. stream框架提供了类似的功能。

这里有一个使用番石榴的解决方案

private boolean checkUserListContainName(List<User> userList, final String targetName){

    return FluentIterable.from(userList).anyMatch(new Predicate<User>() {
        @Override
        public boolean apply(@Nullable User input) {
            return input.getName().equals(targetName);
        }
    });
}

如果您需要执行此List。重复包含(字段值等于x的对象),一个简单而有效的解决方案是:

List<field obj type> fieldOfInterestValues = new ArrayList<field obj type>;
for(Object obj : List) {
    fieldOfInterestValues.add(obj.getFieldOfInterest());
}

然后是列表。contains(字段值等于x的对象)将与fieldOfInterestValues.contains(x)具有相同的结果;

尽管JAVA 8 SDK有很多收集工具库可以帮助你工作,例如: http://commons.apache.org/proper/commons-collections/

Predicate condition = new Predicate() {
   boolean evaluate(Object obj) {
        return ((Sample)obj).myField.equals("myVal");
   }
};
List result = CollectionUtils.select( list, condition );

二分查找

您可以使用集合。binarySearch用于搜索列表中的元素(假设列表是有序的):

Collections.binarySearch(list, new YourObject("a1", "b",
                "c"), new Comparator<YourObject>() {

            @Override
            public int compare(YourObject o1, YourObject o2) {
                return o1.getName().compareTo(o2.getName());
            }
        });

如果该对象不存在于集合中,它将返回一个负数,否则将返回该对象的索引。有了它,您可以使用不同的搜索策略搜索对象。