我有答案课程和用户课程。
答案有getUser()
,用户有getPoints()
从答案列表中我想得到一个按点排序的用户哈希集。我试过以下:
Set<User> collectSet = list.stream().map(Answer::getUser)
.sorted(Comparator.comparing(User::getPoints))
.collect(Collectors.toCollection(HashSet::new));
collectSet.forEach(a -> System.out.println(a.toString()));
不幸的是,这似乎并未保留订单。输出总是不同的。
有趣的是,列表的相同示例可以正常工作
List<User> collectList = list.stream().map(Answer::getUser)
.sorted(Comparator.comparing(User::getPoints))
.collect(Collectors.toList());
collectList.forEach(a -> System.out.println(a.toString()));
我做错了什么?
答案 0 :(得分:5)
Debug.Print "Attribute Text: ", Attribute.Text
首先,您要根据某些 Collectors.toCollection(LinkedHashSet::new)
对这些条目进行排序 - 给予他们&#34;一些&#34;顺序,但然后你把它们放入Comparator
(订单被破坏),因此结果不同。使用HashSet
收集它们以保留排序顺序。
如果您仍想将它们收集到LinkedHashSet
,您可以:
List
操作本身的顺序( yourList.stream()
.sorted(....)
.distinct()
.collect(Collectors.toList())
vs distinct
)matters
答案 1 :(得分:3)
HashSet不会保留插入顺序,但List会保留。您可以尝试使用LinkedHashSet。
修改强>
另一种方法是使用TreeSet。它是一个集合,因此删除了重复的值。并且元素在插入时进行排序。使用方法compareTo
(由Comparable接口提供)进行排序。
例如:
// Answer class
public class Answer {
private final User user;
public Answer(final User user) {
this.user = user;
}
public User getUser() {
return user;
}
}
// User class
public class User implements Comparable<User> {
private final int points;
public User(final int points) {
this.points = points;
}
public int getPoints() {
return points;
}
@Override
public int compareTo(User other) {
// Sort user by their points (ascending order)
return points - other.points;
}
@Override
public String toString() {
return "User{" + "points=" + points + '}';
}
}
然后在你的主要代码中:
// Main
List<Answer> answers = Arrays.asList(
new Answer(new User(0)),
new Answer(new User(20)),
new Answer(new User(1)),
new Answer(new User(20)),
new Answer(new User(10))
);
answers
.stream()
.map(Answer::getUser)
.collect(Collectors.toCollection(TreeSet::new))
.forEach(System.out::println);
输出:
User{points=0}
User{points=1}
User{points=10}
User{points=20}
答案 2 :(得分:1)
您可能想要使用TreeSet
。
两个用户相同没有。点数不相等,因此用户应该有一些uniqueId
。
我将其视为userId
此处不需要hashCode
,equals
(但很高兴见documentation),因为TreeSet
使用Comparator
(或User
类可以实现Comparable
)来确定两个元素是否相等。
TreeSet<User> users = answers.stream()
.map(Answer::getUser)
.collect(Collectors.toCollection(() -> new TreeSet<User>(
Comparator.comparingInt(User::getPoints).thenComparing(User::getUserId))));