Отфильтровать пользователей и сгруппировать их по возрасту

21. Отфильтровать пользователей и сгруппировать их по возрасту

Условие задачи:
Дан класс User, содержащий имя пользователя, возраст и список групп.

Необходимо с помощью Stream API и Java 11 реализовать два метода:

  • consumeFilter() — получить пользователей старше 20 лет, которые состоят хотя бы в одной группе, имя которой содержит строку "Order";
  • consumeGroupByAge() — сгруппировать пользователей по возрасту.

Код:

import lombok.Data;

@Data
class User {
    private String username;
    private Integer age;
    private List<Group> groups;
}

@Data
class Group {
    private String name;
}

public class UserConsumer {

    public List<User> consumeFilter(Stream<User> usersStream) {
        // получить список пользователей,
        // которые в возрасте > 20 лет
        // и состоят в группе, имя которой
        // содержит вхождение строки "Order"
    }

    public Map<Integer, List<User>> consumeGroupByAge(
            Stream<User> usersStream
    ) {
        // сгруппировать пользователей по возрасту
    }
}

Спойлеры к решению

Подсказки
💡 Для проверки возраста используй filter().
💡 Для проверки групп можно вызвать stream() у списка groups.
💡 anyMatch() позволяет проверить, есть ли хотя бы одна подходящая группа.
💡 Для группировки пользователей по возрасту используй Collectors.groupingBy().

Решение
public List<User> consumeFilter(Stream<User> usersStream) {
    return usersStream
            .filter(user -> user.getAge() > 20)
            .filter(user -> user.getGroups().stream()
                    .anyMatch(group ->
                            group.getName().contains("Order")
                    ))
            .collect(Collectors.toList());
}

public Map<Integer, List<User>> consumeGroupByAge(
        Stream<User> usersStream
) {
    return usersStream.collect(
            Collectors.groupingBy(User::getAge)
    );
}

В consumeFilter() сначала остаются только пользователи старше 20 лет:

.filter(user -> user.getAge() > 20)

Затем:

user.getGroups().stream()
        .anyMatch(group ->
                group.getName().contains("Order")
        )

проверяет, есть ли у пользователя хотя бы одна группа, название которой содержит "Order".

Для Java 11 список собирается через:

.collect(Collectors.toList())

В consumeGroupByAge():

Collectors.groupingBy(User::getAge)

создаёт Map, где ключ — возраст пользователя, а значение — список пользователей этого возраста.