根据对象中的变量从对象列表中获取对象

时间:2011-06-05 10:14:11

标签: java list collections comparator

我有User对象列表,我只想根据User对象中的变量从List中获取User对象。

public class User {

    private int id;

    private String sex;

    private int age;

    private String country;

    /**
     * Getter and setter for all variables
     */
}

我有这样的模型类。现在我有User对象列表。

List<User> users = new ArrayList<User>();

如果用户是男性,我想从用户列表中获取对象。

List<User> ageList = new ArrayList<User>();
for(User object : users) {
    if(object.getSex().equals("Male")){
        ageList.add(object);
    }
}

我不喜欢上述方法。有没有更好的方法来根据对象中的变量从对象列表中获取对象..?

Java Collections有没有函数..?我们可以使用Java Comparator解决这个问题..?

5 个答案:

答案 0 :(得分:8)

如果您使用的是Guava,则可以使用Collections2.filter

Collection<User> males = Collections2.filter(users, new Predicate<User>() {
    @Override
    public boolean apply(User user) {
        return user.getSex().equals("Male");
    }
});

使用Java 8,您可以做得更好:

Collection<User> males = Collections2.filter(users, user -> user.getSex().equals("Male"));

答案 1 :(得分:3)

您可以使用lambda函数和反射来完成此操作。但是,由于Java不支持闭包,您会发现这种方法更容易出错,需要更多代码并且速度更慢。

如果你想要一个快速的方法来做到这一点,你可以掌握一个Map&lt; Sec,List&lt; User&gt;&gt;或MultiMap。

顺便说一句:我会用Enum来表达这个人的性别。你应该能够限制自己的几种可能性;)你可以用国家做同样的事情。

答案 2 :(得分:2)

我在java8中找到了一种带流过滤器的方法

List<User> males = users.stream().filter(u -> u.getSex().equals("Male")).collect(Collectors.toList());

答案 3 :(得分:1)

对于简单的过滤器,我喜欢lambdaj onliners语法: http://code.google.com/p/lambdaj/wiki/LambdajFeatures

List<User> ageList = filter(having(on(User.class).getSex(), equalTo("Male")), users);

对于复杂条件,最好创建单独的滤镜效果。

答案 4 :(得分:0)

使用MultiValueMap中的Apache common collectionMap<String List<User>>只是在开头时分割用户,如果根据性别获得用户就是您所需要的。

只要您想从未分类的集合中获取特定用户,就必须搜索整个集合。所以没有更好的方法来检索它。但是,您可以在表面下隐藏此逻辑。

Apache公共集合(以及Guava,Chris Jester-Young提到)提供CollectionUtils.select(),您需要做的就是实现Predicate。 (查看Chris Jester-Young的答案以获得更好的解释)

或者,不是使用集合来传递用户,而是将其设置为UsersUserPack之类的对象。然后,您可以实现方法调用getMaleUsers()以返回对象内的所有男性用户。如果你需要经常操作特定的对象,这个技巧非常有用。