【问题标题】:Grouping and Sorting a Collection with Java 8 Streams使用 Java 8 流对集合进行分组和排序
【发布时间】:2016-11-16 20:10:37
【问题描述】:

我有一个我想根据年龄分组的人员列表(group1 的年龄 =20)并使用 Java 8 根据姓名和年龄对每个组进行排序: 人员名单:

第一组:

Ane 12
Col 14

第 2 组:

James 24
thomas 34
Xavier 55

我想使用 Java 8 来做这样的事情:

list.stream().collect(Collectors.groupingBy(...

【问题讨论】:

  • 您希望群组按姓名优先还是年龄优先排序?
  • @akaliza 是关于将列表分成两组或按多个年龄范围分组的问题?如果是关于按年龄范围分组,您可以更新您的问题以清楚起见(并让我修复我的答案建议:))

标签: java lambda java-8 grouping


【解决方案1】:

你可以通过以下方式得到你想要的:

  • 按年龄(然后按姓名)对您的整个集合进行排序。
  • 对其进行分区。

注意每个分区的顺序会保持:

import static java.util.Comparator.comparing;
import static java.util.stream.Collectors.partitioningBy;

people.stream()
  .sorted(
     comparing(Person::getAge)
       .thenComparing(Person::getName))
  .collect(partitioningBy(p -> p.getAge() >= 20))

感谢 Christoffer 的改进建议:斯堪的纳维亚 Java 必须像一套宜家组装说明一样流畅:)

【讨论】:

  • 你应该使用Comparator.comparing(Person::getAge)。
  • 谢谢,这样更干净:)
  • 另外,为了更干净,import static java.util.Collectors.partitioningBy 和 import static java.util.Comparator.comparing;
【解决方案2】:

您将希望改用partitioningBy 收集器。它将允许您指定一个谓词并返回一个以布尔值为键的映射:

Map<Boolean, List<?>> partitioned = list.stream().sorted(...).collect(Collectors.partitioningBy(...));

【讨论】:

  • 如果我想要 20 到 50 岁的人怎么办?我可以链接 partitioningBy 吗?
  • 并非如此。在这种情况下,您需要编写一个为每个组返回不同值的函数,然后使用该函数执行groupingBy。
  • 我明白,我们有一个谓词,所以我可以这样做 p -> p.getAge() >= 20 && p.getAge()
  • 啊,我以为你想要三个组:50。如果你想要一组 20 到 50 人,另一组是其他人,那就行了。
  • 基本上是的。
猜你喜欢
  • 1970-01-01
  • 2016-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-18
  • 2011-10-20
  • 2013-04-30
相关资源
最近更新 更多