Java 使用流时创建已排序集

Java 使用流时创建已排序集,java,java-8,java-stream,Java,Java 8,Java Stream,我有一个用户类,其中包含姓名、类型和年龄,然后这些用户的长列表就是我的输入list users=db.getUsers() 我正试图从中创建一组所有独特的用户,但问题是我也希望根据年龄对他们进行排序。我目前使用- Set<User> set = users.stream().collect(Collectors.toSet()); Set Set=users.stream().collect(Collectors.toSet()); 如何同时对该集合进行排序,有什么想法吗?使用C

我有一个用户类,其中包含姓名、类型和年龄,然后这些用户的长列表就是我的输入
list users=db.getUsers()

我正试图从中创建一组所有独特的用户,但问题是我也希望根据年龄对他们进行排序。我目前使用-

Set<User> set = users.stream().collect(Collectors.toSet());
Set Set=users.stream().collect(Collectors.toSet());
如何同时对该集合进行排序,有什么想法吗?

使用Comparator on方法


正如@nullpointer和@Ravindra所指出的,我没有添加集合(如TreeSet或LinkedHashSet)

您可以在流式处理时对
进行排序,并将其收集到
集合中

Set<User> set = new HashSet<>(users);   // remove duplicates via equals
TreeSet<User> userSet = set.stream().collect(Collectors.toCollection(user));
比如:

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

假设在用户类中正确地实现了
equals
hashcode
方法,这里有一种方法

Set<User> uniqueUsers = new HashSet<>(users);
Set<User> sortedUniqueUsers = uniqueUsers.stream()
    .sorted(Comparator.comparingInt(User::getAge))
    .collect(Collectors.toSet());
Set uniqueUsers=新HashSet(用户);
Set sortedUniqueUsers=uniqueUsers.stream()
.sorted(Comparator.comparingInt(用户::getAge))
.collect(收集器.toSet());

在未排序的集合中谈论顺序是没有意义的。如果您想要按年龄排序的集合,您应该使用类似于
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));

如何定义唯一性?@Ravindra一个用户是重复的,因为它与另一个用户具有相同的所有属性。您是否覆盖了
User
中的
hashCode
equals
方法?@Federicoperalthaffner是的,我们已经实现了它。请注意,这两个任务(按唯一性过滤和按年龄排序)可以由数据库完成。这可能会更快,具体取决于您的场景(使用数据库上的索引,为优化器提供一些可以使用的东西,并避免网络上的重复)。你甚至可以在DB上考虑一个唯一的约束。当你在<代码> >排序< /代码>中进行比较时,当你做了<代码>收藏夹。toTeET()/代码>时,排序顺序不被维护。这是一个基于散列的集合。@nullpointer感谢您指出。我已经改正了我的错误answer@RavindraRanwala谢谢你指出。我已经添加了集合为什么我们在这里使用
TreeSet
,而不是在其他答案中使用
LinkedHashSet
?前面的例子中,
uniqueUsers
可能是非常清楚的,IMHO。当我只是用-->更新它时,这个确切的例子无法生成排序的最终集合。Collectors.toCollection(LinkedHashSet::new)成功了。为什么我们在这里使用
TreeSet
,而在其他答案中不使用
LinkedHashSet
?@Mani这取决于你想要什么。
TreeSet
是一个排序集,这意味着如果您迭代它,您将看到按照年龄排序的输出
LinkedHashSet
是一个集合,其中运行着一个链接列表。它保持插入顺序,因此如果按年龄插入,它将显示为已排序。最大的区别在于,添加新用户时,我的答案将保持排序,而
LinkedHashSet
答案则不会。此外,
TreeSet
知道它是按照特定顺序排序的,如果有人问起,它会报告。它还提供了基于该知识的操作,例如,您可以请求小于特定参考值的所有元素的子集,或者请求缺少值的下一个较大或较小元素,等等。顺便说一下,您不需要在此处使用中间变量,
TreeSet users=users.stream().collect(Collectors.toCollection()->新树集(Comparator.comparingit(User::getAge))也行。@Holger同意,但也许我写的方式更容易阅读:-)这是风格的问题,我不敢讨论风格…这只是一个小小的补充,读者可以自己决定。
Set<User> users = new HashSet<>(users);
Set<User> uniqueUsers = new HashSet<>(users);
Set<User> sortedUniqueUsers = uniqueUsers.stream()
    .sorted(Comparator.comparingInt(User::getAge))
    .collect(Collectors.toSet());
Comparator<User> byAge = Comparator.comparingInt(User::getAge);

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

TreeSet<User> userSet = users.stream().collect(Collectors.toCollection(user));
Set<User> set = new HashSet<>(users);   // remove duplicates via equals
TreeSet<User> userSet = set.stream().collect(Collectors.toCollection(user));