46. Найти младшего пользователя для каждого имени
Условие задачи:
Дан список пользователей List<User>. Необходимо получить младшего пользователя для каждого имени.
Поля класса User:
String name;String surname;int age.
Код:
List<User> users = new ArrayList<>();
users.add(new User("Alex", "Ivanov", 28));
users.add(new User("Alex", "Petrov", 21));
users.add(new User("Mary", "Ivanova", 34));
users.add(new User("Mary", "Petrova", 25));
users.add(new User("Mary", "Sidonova", 33));
users.add(new User("Anton", "Ivanov", 33));
users.add(new User("Anton", "Petrov", 33));
users.add(new User("Anton", "Sidorov", 33));
System.out.println("Hello, World!");
Спойлеры к решению
Подсказки
💡 Пользователей нужно сгруппировать по полю
💡 При совпадении имён нужно оставить пользователя с минимальным возрастом.
💡 Удобно использовать
💡 Для сравнения пользователей подойдёт
name.💡 При совпадении имён нужно оставить пользователя с минимальным возрастом.
💡 Удобно использовать
Collectors.toMap() с функцией объединения значений.💡 Для сравнения пользователей подойдёт
Comparator.comparingInt(User::getAge).Решение
Map<String, User> youngestByName = users.stream()
.collect(Collectors.toMap(
User::getName,
Function.identity(),
BinaryOperator.minBy(
Comparator.comparingInt(User::getAge)
)
));
youngestByName.forEach((name, user) ->
System.out.println(
name + " -> "
+ user.getSurname()
+ ", age "
+ user.getAge()
)
);
Метод toMap() использует имя пользователя как ключ:
User::getName
При появлении двух пользователей с одинаковым именем функция объединения оставляет младшего:
BinaryOperator.minBy(
Comparator.comparingInt(User::getAge)
)
Результат:
Alex -> Petrov, age 21
Mary -> Petrova, age 25
Anton -> Ivanov, age 33
Если у нескольких пользователей с одним именем одинаковый минимальный возраст, останется первый встретившийся пользователь.
Временная сложность — O(n), дополнительная память — O(k), где k — количество уникальных имён.