Представьте, что у вас есть список людей, Робертс, Полс, Ричардс и т. Д., Это люди, сгруппированные по имени в Map<String, List<Person>>
.Вы хотите найти самого старшего Пола, Роберта и т.д. ... Вы можете сделать это так:
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);
}
Скажем, я хочу получить отображение в виде 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))));
Шаги выше:
- Сгруппировать по имени в
Map<String/*Name*/, List<Person>>
- Отобразить, что
List<Person>
вList<Integer>
- Найти максимальное целое число в этих списках.
Мне было интересно, как это сделать:
- Сгруппировать по имени в
Map<String, List<Person>>
- Найдите самого старого человека в названии каждой группы, получив
Map<String, Person>
- Преобразование
Map<String, Person>
в Map<String, Integer>
.И я хочу сделать все это внутри цепочки группировки By, уменьшая и сопоставляя.
Это "псевдокод":
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*/)));
Как мне этого добиться?