Как найти дубликаты в списке объектов, отсортировать по полям и оставить нужные?
По итогу сортировки нужно удалить дубликаты с одинаковым именем, оставив имеющего наибольший возраст. Вариант ниже не работает, потому как просто ищет дубликаты, не сортируя. Подойдут любые варианты через циклы или stream API.
People people1 = new People("Ivan", 15);
People people2 = new People("Petr", 35);
People people3 = new People("Ivan", 25);
People people4 = new People("Petr", 30);
People people5 = new People("Oleg", 25);
People people6 = new People("Ivan", 20);
People people7 = new People("Boris", 35);
List<People> peopleList = Arrays.asList(people1, people2, people3, people4, people5, people6, people7);
List<People> duplicates = peopleList.stream()
//группируем в map (пользователь -> количество вхождений)
.collect(Collectors.groupingBy(Function.identity()))
//проходим по группам
.entrySet()
.stream()
//отбираем пользователей, встречающихся более одного раза
.filter(e -> e.getValue().size() > 1)
//вытаскиваем ключи
.map(Map.Entry::getKey)
//собираем в список
.collect(Collectors.toList());
Ответы (1 шт):
Автор решения: Nowhere Man
→ Ссылка
Для группировки по имени следует использовать соответствующий геттер.
Также достаточно добавить коллектор Collectors.maxBy, принимающего соответствующий компаратор по геттеру для возраста и возвращающего Optional<People>, затем значения можно преобразовать дополнительным проходом:
List<People> oldies = peopleList.stream()
.collect(Collectors.groupingBy(
People::getName, // или People::name в случае record
Collectors.maxBy(Comparator.comparingInt(People::getAge)) // People::age
)) // Map<String, Optional<People>>
.values()
.stream() // Stream<Optional<People>>
.map(Optional::get) // Stream<People>
.collect(Collectors.toList());
Или же можно применить Collectors.collectingAndThen, в котором преобразовать результат Optional<People> при помощи ссылки на метод Optional::get:
List<People> oldies2 = new ArrayList<>(peopleList.stream()
.collect(Collectors.groupingBy(
People::getName,
Collectors.collectingAndThen(
Collectors.maxBy(Comparator.comparingInt(People::getAge)), Optional::get
)
))
.values());