Для примера я предполагаю следующий класс.
public class Activity {
int id;
LocalDate date;
// constructor, getters, toString method
}
Чтобы получить самую последнюю дату для каждого ID:
List<Activity> elements = // …
Map<Integer, LocalDate> latestDates = elements.stream()
.collect(Collectors.groupingBy(Activity::getId,
Collectors.mapping(Activity::getDate,
Collectors.collectingAndThen(Collectors.maxBy(LocalDate::compareTo),
Optional::get))));
Я попробовал код со следующим списком:
4 2018-03-07
3 2018-03-14
4 2018-02-11
3 2018-02-18
1 2018-01-24
2 2018-01-02
5 2018-03-13
4 2017-10-01
5 2018-01-09
3 2017-10-11
Полученная карта печатается как:
{1 = 2018-01-24, 2 = 2018-01-02, 3 = 2018-03-14, 4 = 2018-03-07, 5 = 2018-03-13}
Если вам трудно следовать за кодом потока, используйте вместо него цикл.
Редактировать: мое предыдущее выражение потока было:
Map<Integer, LocalDate> latestDates = elements.stream()
.collect(Collectors.groupingBy(Activity::getId,
Collectors.collectingAndThen(Collectors.maxBy(Comparator.comparing(Activity::getDate)),
optAct -> optAct.get().getDate())));
Несмотря на то, что старый короче, я считаю новый более естественным в том смысле, что он отображает объекты деятельности на даты до нахождения самой последней даты (а не наоборот). Если вам нужны действия (не только даты), старое выражение будет лучшей отправной точкой.