Вы можете попробовать следующий код потока, который агрегирует по ID
, а затем находит максимальную оценку, используя двухуровневую сортировку, сначала по оценке, а затем по дополнительному идентификатору в случае привязки к оценке:
import static java.util.Collections.reverseOrder;
import static java.util.Comparator.comparing;
Map<Long, Optional<Person>> result1 = records.stream()
.collect(Collectors.groupingBy(Person::getId,
Collectors.maxBy(
Comparator.comparing(Person::getScore)
.thenComparing(reverseOrder(comparing(Person::getOptionalId))))));
Optional[ID: 1 Score: 90 OptionalId: 2]
Optional[ID: 2 Score: 100 OptionalId: 3]
Хитрость здесь в том, чтобы изменить порядок сортировки только для необязательного идентификатора, который мы хотим, чтобы он был восходящим, а не нисходящим.Порядок сортировки по умолчанию будет убывающим, потому что мы вызываем Collections.maxBy
.
Я цитирую этот замечательный вопрос SO для помощи с обратным синтаксисом.Кроме того, я позаимствовал код плиты котла у @mayamar для настройки следующей демонстрации:
Демо
(демонстрация только для демонстрационных целей)