当前位置:  开发笔记 > 编程语言 > 正文

查找集合中具有给定属性的所有对象

如何解决《查找集合中具有给定属性的所有对象》经验,为你挑选了6个好方法。

我有一些复杂的物体,比如猫,它有许多属性,如年龄,最喜欢的猫粮等.

一堆Cats存储在Java Collection中,我需要找到所有3岁的猫,或者那些喜欢的猫粮是Whiskas的猫.当然,我可以编写一个自定义方法来查找具有特定属性的Cats,但这对于许多属性来说很麻烦; 这有什么通用的方法吗?



1> Brian Dilley..:

尝试commons集合API:

List bigList = ....; // master list

Collection smallList = CollectionUtils.select(bigList, new Predicate() {
    public boolean evaluate(Object o) {
        Cat c = (Cat)o;
        return c.getFavoriteFood().equals("Wiskas") 
            && c.getWhateverElse().equals(Something);
    }
});

当然,您不必每次都使用匿名类,您可以Predicate为常用搜索创建接口的实现.


请注意,在比较字符串时,必须使用.equals方法,否则您要比较内存引用位置,请参阅:http://stackoverflow.com/questions/767372/java-string-equals-versus

2> 小智..:

我一直在使用Google Collections(现在称为Guava)来解决这类问题.有一个名为Iterables的类可以将名为Predicate的接口作为一个非常有用的方法的参数.

Cat theOne = Iterables.find(cats, new Predicate() {
    public boolean apply(Cat arg) { return arg.age() == 3; }
});

检查它在这里!



3> Adrian Shum..:

使用Java 8 lambda表达式,您可以执行类似的操作

cats.stream()
    .filter( c -> c.getAge() == 3 && c.getFavoriteFood() == WHISKAS )
    .collect(Collectors.toList());

在概念上与Guava Predicate方法相同,但使用lambda看起来更清晰

可能不是OP的有效答案,但值得注意的是有相似需求的人.:)



4> David Z..:

您可以编写一个方法,该方法接受定义check(Cat)方法的接口实例,其中该方法可以使用您想要的任何属性检查来实现.

更好的是,让它通用:

public interface Checker {
    public boolean check(T obj);
}

public class CatChecker implements Checker {
    public boolean check(Cat cat) {
        return (cat.age == 3); // or whatever, implement your comparison here
    }
}

// put this in some class
public static  Collection findAll(Collection coll, Checker chk) {
    LinkedList l = new LinkedList();
    for (T obj : coll) {
         if (chk.check(obj))
             l.add(obj);
    }
    return l;
}

当然,就像其他人说的那样,这就是关系数据库的用途......


(1)很高兴知道它是如何实现的(2)通常不值得为这样一个简单的方法引入一个额外的库.
怎么了?没有人听说过Commons Collections,Google Collections或Hamcrest系列吗?我无法相信这有很多赞成或者被接受.
我没有使用Comparator的原因是Comparator应该对集合强加一个总排序,而我们需要的只是对某些条件的布尔测试.正在检查的财产可能没有任何有意义的订单.
我会说同样的,但建议使用Comparator而不是自定义界面.
@David:参数+1(+1).看了这一千次:导入额外的lib,额外的jar,一个20行的单个类的额外回购.保持比例感!

5> flybywire..:

我建议使用Jxpath,它允许你对对象图进行查询,就好像它在xpath那样

JXPathContext.newContext(cats).
     getValue("//*[@drinks='milk']")


+1有趣(即使XPath不是学习有效使用的最简单方法)

6> 小智..:

再次使用commons集合API:当您单独实现谓词时,您将获得"检查器"类型代码: -

public class CatPredicate implements Predicate {

    private int age; 


    public CatPredicate(int age) {
        super();
        this.age = age;
    }


    @Override
    public boolean evaluate(Object o) {
        Cat c (Cat)o;
        return c.getAge()==this.age;
    }

}

被用作: -

CollectionUtils.filter(catCollectionToFilter, new CatPredicate(3))

推荐阅读
echo7111436
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有