java - 流分组后如何聚合分组实体

标签 java java-8 java-stream groupingby

我有一个简单的类 Person:

class Person {
    String firstName;
    String lastName;
    //getter, setter, constructor, toString
}

还有一个 Persons 的输入列表,例如:

List<Person> myList = List.of(
        new Person("Helena", "Graves"),
        new Person("Jasmine", "Knight"),
        new Person("Phoebe", "Reyes"),
        new Person("Aysha", "Graham"),
        new Person("Madeleine", "Jenkins"),
        new Person("Christina", "Johnson"),
        new Person("Melissa", "Carpenter"),
        new Person("Marie", "Daniel"),
        new Person("Robin", "French"),
        new Person("Tamara", "Wyatt"),
        new Person("Freya", "Montgomery"),
        new Person("Lacey", "Todd"),
        new Person("Heather", "Parker"),
        new Person("Lauren", "Wright"),
        new Person("Annie", "Bradley")
);

现在我需要将上面的列表按人员姓氏的第一个字符进行分组,然后再次对这些组进行分组,以便所有从 A-H 开始的姓氏属于一个组,下一组为那些以 I-N 开头,最后以 O-Z 开头。

我已经可以按姓氏的第一个字符对列表进行分组:

myList.stream()
        .collect(Collectors.groupingBy(p -> String.valueOf(p.getLastName().charAt(0))))
        .entrySet()
        .forEach(System.out::println);

这给了我:

P=[Person{Heather, Parker}]
B=[Person{Annie, Bradley}]
R=[Person{Phoebe, Reyes}]
C=[Person{Melissa, Carpenter}]
T=[Person{Lacey, Todd}]
D=[Person{Marie, Daniel}]
F=[Person{Robin, French}]
W=[Person{Tamara, Wyatt}, Person{Lauren, Wright}]
G=[Person{Helena, Graves}, Person{Aysha, Graham}]
J=[Person{Madeleine, Jenkins}, Person{Christina, Johnson}]
K=[Person{Jasmine, Knight}]
M=[Person{Freya, Montgomery}]

很难从这里开始,因为我需要进一步汇总以上内容以获得包含三个条目/键的映射。期望的输出:

Map<String, List<Person>> result = ...

A-H = [Person{Helena, Graves}, Person{Aysha, Graham}, Person{Melissa, Carpenter}, Person{Marie, Daniel}, Person{Robin, French}, Person{Annie, Bradley}]
I-N = [Person{Jasmine, Knight}, Person{Madeleine, Jenkins}, Person{Christina, Johnson}, Person{Freya, Montgomery}]
O-Z = [Person{Phoebe, Reyes}, Person{Tamara, Wyatt}, Person{Lacey, Todd}, Person{Heather, Parker}, Person{Lauren, Wright}]

最佳答案

您应该稍微更改分类器函数以组合一系列字符。

另外,可能需要对entrySet()进行排序(或者采集到 map 时使用SortedMap/TreeMap):

myList.stream()
      .collect(Collectors.groupingBy(
          p -> p.getLastName().charAt(0) < 'I' ? "A-H" : 
               p.getLastName().charAt(0) < 'O' ? "I-N" : "O-Z"
      ))
      .entrySet()
      .stream()
      .sorted(Map.Entry.comparingByKey())
      .forEach(System.out::println);

输出:

A-H=[Person {Helena Graves}, Person {Aysha Graham}, Person {Melissa Carpenter}, Person {Marie Daniel}, Person {Robin French}, Person {Annie Bradley}]
I-N=[Person {Jasmine Knight}, Person {Madeleine Jenkins}, Person {Christina Johnson}, Person {Freya Montgomery}]
O-Z=[Person {Phoebe Reyes}, Person {Tamara Wyatt}, Person {Lacey Todd}, Person {Heather Parker}, Person {Lauren Wright}]

关于java - 流分组后如何聚合分组实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69681887/

相关文章:

java - 执行 Observables 映射

java - 如何在 Java 中将 BigDecimal 转换为具有 2 位小数的 float

java-8 - 使用 streams/collect 转换 Map

java - 将 List<HashMap<String, Object>> 转换为流

java - 使用 Kotlin 使用 OkHttp 发送 JSON 数据

javax.comm 以及如何修复 java.lang.NoClassDefFoundError

java - 我们应该如何为空值管理 jdk8 流

java-8 - Java 8 在分组时不保持顺序

java - Spring 批处理 : Profiling a batch processing application

java - 在 mongo 中插入记录时出现重复键错误索引