如何在collect内部的java流中将Map <String,Person>转换为Map <String,Integer>?

Cod*_*Man 5 java java-8 java-stream

假设您有一个人名单,罗伯茨,保罗,理查兹等,这些人按名字分组为Map<String, List<Person>>。您想找到最古老的Paul,Robert等...您可以这样做:

public static void main(String... args) {
        List<Person> people = Arrays.asList(
                new Person(23, "Paul"),
                new Person(24, "Robert"),
                new Person(32, "Paul"),
                new Person(10, "Robert"),
                new Person(4, "Richard"),
                new Person(60, "Richard"),
                new Person(9, "Robert"),
                new Person(26, "Robert")
        );

        Person dummy = new Person(0, "");
        var mapping = people.stream().collect(groupingBy(Person::getName, reducing(dummy, (p1, p2) -> p1.getAge() < p2.getAge() ? p2 : p1)));
        mapping.entrySet().forEach(System.out::println);
    }
Run Code Online (Sandbox Code Playgroud)

说,我想以Map<String, Integer>而不是的形式获取映射Map<String, Person>,我可以这样做:

var mapping = people.stream().collect(groupingBy(Person::getName, mapping(Person::getAge, reducing(0, (p1, p2) -> p1 < p2 ? p2 : p1))));
Run Code Online (Sandbox Code Playgroud)

上面的步骤是:

  • 按名称分组 Map<String/*Name*/, List<Person>>
  • 映射List<Person>List<Integer>
  • 在这些列表中找到最大整数。

我想知道如何做:

  • 按名称分组 Map<String, List<Person>>
  • 在每个组名中找到年龄最大的人, Map<String, Person>
  • 转换Map<String, Person>Map<String, Integer>。我想在groupingBy,reduce和mapping的整个链中进行所有操作。

这是“伪代码”:

var mapping = people.stream().collect(groupingBy(Person::getName, reducing(dummy, (p1, p2) -> p1.getAge() < p2.getAge() ? p2 : p1 /*, have to write some other collector factory method here*/)));
Run Code Online (Sandbox Code Playgroud)

我该如何实现?

Mis*_*sha 5

使用3参数版本的toMapcollector是更简单的方法

people.stream().collect(toMap(
        Person::getName, 
        Person::getAge, 
        Integer::max
    ));
Run Code Online (Sandbox Code Playgroud)