我有一个 User 类,其中包含名称,类型和年龄,然后一长串这些用户就是我的输入List<User> users = db.getUsers();
。
我正在尝试以此创建一组所有唯一用户,但是问题是我也在寻找根据年龄对其进行排序的用户。我目前使用过-
Set<User> set = users.stream().collect(Collectors.toSet());
还有什么办法同时对这个集合排序?
答案 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
中,但是还会有一个复制步骤。
使用TreeSet
和LinkedHashSet
之间的主要区别在于维护排序顺序。使用TreeSet
,在添加新用户时,将保持排序。使用LinkedHashSet
时,添加新用户可能会破坏按年龄排序的顺序,因为LinkedHashSet
仅维护插入顺序。
编辑:
根据下面@Federico的评论,实际的TreeSet
将使用其比较器来确定User
对象的相等性。如果您想首先通过equals()
方法删除所有重复的用户,那么我们可以先将所有用户添加到HashSet
,然后使用上述方法将其添加到{{1} }。
TreeSet
答案 1 :(得分:2)
这是一种假设您已经在User类中正确实现了equals
和hashcode
方法的方法。
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
应该与此相当。即已覆盖equals
和hashCode
。
旁注 :您现有的代码可以简化为:
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)