在使用流时创建排序集

Man*_*ani 3 java java-8 java-stream

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

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

Set<User> set = users.stream().collect(Collectors.toSet());
Run Code Online (Sandbox Code Playgroud)

如何同时对这个集合排序,有什么想法吗?

Nam*_*man 10

您可以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
Run Code Online (Sandbox Code Playgroud)

请注意,您的对象User应该具有可比性。即已覆盖equalshashCode

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

Set<User> users = new HashSet<>(users);
Run Code Online (Sandbox Code Playgroud)


Tim*_*sen 8

在非排序集中谈论顺序是没有意义的。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));
Run Code Online (Sandbox Code Playgroud)

如果上述代码对您不利,您也可以将当前的用户集添加到中TreeSet,但是还会有一个复制步骤。

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

编辑:

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

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

  • @Mani这取决于您想要什么。TreeSet是一个排序的集合,这意味着如果您对其进行迭代,您将看到根据年龄对输出进行排序。LinkedHashSet是一个带有链表的集合。它保持插入顺序,因此,如果您根据年龄插入,它将显示为已排序。最大的不同是,添加新用户时我的答案将保持排序,而“ LinkedHashSet”答案则不会。 (2认同)

Rav*_*ala 6

这是一种方法,假设您已经equalshashcodeUser 类中正确实现了方法。

Set<User> uniqueUsers = new HashSet<>(users);
Set<User> sortedUniqueUsers = uniqueUsers.stream()
    .sorted(Comparator.comparingInt(User::getAge))
    .collect(Collectors.toCollection(LinkedHashSet::new));
Run Code Online (Sandbox Code Playgroud)

  • 恕我直言,前面的“uniqueUsers”示例非常清楚。 (3认同)
  • 当我只是使用 --&gt; 更新它时,这个确切的示例无法生成排序的最终集。Collectors.toCollection(LinkedHashSet::new) 它有效。 (3认同)