在使用流时创建排序集

时间:2018-12-19 05:56:39

标签: java java-8 java-stream

我有一个 User 类,其中包含名称,类型和年龄,然后一长串这些用户就是我的输入List<User> users = db.getUsers();

我正在尝试以此创建一组所有唯一用户,但是问题是我也在寻找根据年龄对其进行排序的用户。我目前使用过-

Set<User> set = users.stream().collect(Collectors.toSet());

还有什么办法同时对这个集合排序?

4 个答案:

答案 0 :(得分:4)

说说非排序集中的顺序没有意义。如果您想要按年龄排序的集合,则应该使用TreeSet之类的东西。

Comparator<User> byAge = Comparator.comparingInt(User::getAge);

Supplier<TreeSet<User>> user = () -> new TreeSet<User>(byAge);

TreeSet<User> userSet = users.stream().collect(Collectors.toCollection(user));

如果上面的代码对您来说很丑陋,您也可以将当前的用户集添加到TreeSet中,但是还会有一个复制步骤。

使用TreeSetLinkedHashSet之间的主要区别在于维护排序顺序。使用TreeSet,在添加新用户时,将保持排序。使用LinkedHashSet时,添加新用户可能会破坏按年龄排序的顺序,因为LinkedHashSet仅维护插入顺序。

编辑:

根据下面@Federico的评论,实际的TreeSet将使用其比较器来确定User对象的相等性。如果您想首先通过equals()方法删除所有重复的用户,那么我们可以先将所有用户添加到HashSet,然后使用上述方法将其添加到{{1} }。

TreeSet

答案 1 :(得分:2)

这是一种假设您已经在User类中正确实现了equalshashcode方法的方法。

HashSet<User> uniqueUsers = new HashSet<>(users);
List<User> sortedUniqueUsers = uniqueUsers.stream()
    .sorted(Comparator.comparingInt(User::getAge))
    .collect(Collectors.toList());

答案 2 :(得分:1)

在流式传输并收集到sort时,您可以Set

类似的东西:

Set<User> finalList = users.stream()
        .sorted(Comparator.comparing(User::getAge)) // sort while streaming
        .collect(Collectors.toCollection(LinkedHashSet::new)); 
        // note collecting to a set that maintains the order

请注意,您的对象User应该与此相当。即已覆盖equalshashCode

旁注 :您现有的代码可以简化为:

Set<User> users = new HashSet<>(users);

答案 3 :(得分:0)

stream().sorted()方法上使用比较器

Set<User> set = users.stream().sorted(Comparator.comparing(User::getAge)).collect(Collectors.toCollection(LinkedHashSet::new));

并在User类中实现Comparable

class User implements Comparable<User>{ 

并添加compareTo方法

@Override
public int compareTo(User ob) {
    return age-ob.getAge();
}

正如@nullpointer和@Ravindra指出的那样,我错过了添加Collection(例如TreeSet或LinkedHashSet)