Все операции над списками можно свести к трем основным типам:
- Отображение.
- Фильтрация.
- Агрегация.
Для примеров в этом уроке мы будем использовать класс User
с таким определением:
import java.time.LocalDate;
class User {
// LocalDate хранит дату без времени
private LocalDate birthday;
User(LocalDate birthday) {
this.birthday = birthday;
}
LocalDate getBirthday() {
return birthday;
}
}
Отображение (map)
Отображение — это операция, в которой на основе одного списка, формируется другой, с таким же количеством элементов. Например, у нас есть список пользователей, из которого мы хотим получить список возрастов этих пользователей для каких-то дальнейших вычислений или формирования данных по запросу. Ниже код, выполняющий эту задачу:
import java.util.ArrayList;
import java.time.LocalDate;
import java.time.Period;
var users = List.of(
new User(LocalDate.of(1999, 1, 1)),
new User(LocalDate.of(2010, 5, 8)),
new User(LocalDate.of(2008, 10, 11))
);
var ages = new ArrayList<Integer>();
var currentDate = LocalDate.now();
for (var user : users) {
// Описывает разницу между двумя датами
var age = Period.between(user.getBirthday(), currentDate);
ages.add(age.getYears());
}
System.out.println(ages);
// Вывод в 2023 году
// => [24, 13, 15]
Фильтрация (filter)
Фильтрация — это операция, в результате которой на основе одного списка, формируется другой, с элементами, соответствующими условию фильтрации. Например, мы хотим сформировать список пользователей, которые родились после 2000 года.
import java.util.ArrayList;
import java.time.LocalDate;
var users = List.of(
new User(LocalDate.of(1999, 1, 1)),
new User(LocalDate.of(2010, 5, 8)),
new User(LocalDate.of(2008, 10, 11))
);
var filteredUsers = new ArrayList<User>();
for (var user : users) {
if (user.getBirthday().getYear() >= 2000) {
filteredUsers.add(user);
}
}
System.out.println(filteredUsers.size()); // 2
Фильтрация в чистом виде работает так:
- Новый список по размеру либо такой же, как и исходный, либо меньше, вплоть до того, что он может быть пустым.
- Фильтрация не меняет сами элементы, она только убирает неподходящие. Изменение элементов возможно только тогда, когда фильтрация объединена — например, с отображением.
Агрегация
Агрегация — это операция нахождения какого-то значения, вычисленного на основе анализа всей коллекции. К агрегирующим операциям традиционно относят:
- Нахождение максимального или минимального значения
- Нахождение суммы
- Нахождение среднего значения и медианы
Но агрегация не ограничивается только такими операциями. Более того, результатом агрегации может быть сложная структура, а не простое значение. Например, мы можем захотеть сгруппировать всех пользователей по году рождения. Несмотря на различия, все эти операции сводятся к полному анализу элементов коллекции, так как результат агрегирующей операции зависит от каждого элемента.
Для примера посчитаем самый ранний год рождения:
import java.util.ArrayList;
import java.time.LocalDate;
import java.time.Period;
var users = List.of(
new User(LocalDate.of(1999, 1, 1)),
new User(LocalDate.of(2010, 5, 8)),
new User(LocalDate.of(2008, 10, 11))
);
var minYear = users.get(0).getBirthday().getYear();
for (var user : users) {
var year = user.getBirthday().getYear();
if (year < minYear) {
minYear = year;
}
}
System.out.println(minYear); // => 1999
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.