14. Найти средний возраст мужчин в списке
Условие задачи:
Дан список объектов Person с полями:
name;age;sex.
Необходимо с помощью Stream API найти средний возраст всех мужчин из списка.
Если мужчин в списке нет, результат должен быть пустым OptionalDouble.
Код:
List<Person> persons = Arrays.asList(
new Person("Alice", 25, "female"),
new Person("Bob", 30, "male"),
new Person("Eve", 35, "female"),
new Person("Jack", 28, "male")
);
Пример результата:
29.0
Если мужчин нет:
OptionalDouble.empty
Спойлеры к решению
Подсказки
filter() оставь только мужчин.💡 Через
mapToInt() преобразуй поток Person в поток возрастов.💡 Метод
average() возвращает OptionalDouble.💡
OptionalDouble позволяет корректно обработать случай, когда подходящих элементов нет.Решение
OptionalDouble averageAgeOfMales = persons.stream()
.filter(person -> "male".equalsIgnoreCase(person.getSex()))
.mapToInt(Person::getAge)
.average();
Сначала:
.filter(person -> "male".equalsIgnoreCase(person.getSex()))
оставляет только мужчин.
Вызов equalsIgnoreCase() выполняется у строкового литерала "male", поэтому код не выбросит NullPointerException, если person.getSex() вернёт null.
Затем:
.mapToInt(Person::getAge)
преобразует объекты Person в их возраст, а:
.average()
вычисляет среднее значение и возвращает OptionalDouble.
Для возрастов 30 и 28 результат:
29.0
Если мужчин в списке нет, average() вернёт:
OptionalDouble.empty
Если по условию обязательно требуется получить именно double, можно задать значение для случая отсутствия мужчин:
double averageAgeOfMales = persons.stream()
.filter(person -> "male".equalsIgnoreCase(person.getSex()))
.mapToInt(Person::getAge)
.average()
.orElse(0.0);
Но если отсутствие мужчин должно отличаться от реального среднего возраста 0, предпочтительнее сохранить OptionalDouble.
Временная сложность — O(n), дополнительная память — O(1).