Как преобразовать каждый элемент списка
Короткий ответ
map() применяет функцию к каждому элементу и возвращает поток результатов:
void main() {
var names = List.of("anna", "oleg");
var upper = names.stream().map(String::toUpperCase).toList();
IO.println(upper);
}Результат:
[ANNA, OLEG]Извлечь поле
Частый случай — получить список значений одного поля:
record User(String name, String email) {}
void main() {
var users = List.of(new User("Anna", "anna@site.com"), new User("Oleg", "oleg@site.com"));
IO.println(users.stream().map(User::email).toList());
}Результат:
[anna@site.com, oleg@site.com]Числа
mapToInt() даёт поток чисел, у которого есть sum(), max() и average():
void main() {
var words = List.of("java", "is", "fun");
IO.println(words.stream().mapToInt(String::length).sum());
}Результат:
9Изменить на месте
replaceAll() заменяет каждый элемент изменяемого списка результатом функции:
void main() {
var prices = new ArrayList<>(List.of(10, 20, 30));
prices.replaceAll(p -> p * 2);
IO.println(prices);
}Результат:
[20, 40, 60]Частая ошибка
Использовать forEach() для заполнения другого списка. Это работает, но map() с toList() короче и не требует изменяемого списка снаружи:
void main() {
var names = List.of("anna", "oleg");
var result = new ArrayList<String>();
names.forEach(n -> result.add(n.toUpperCase()));
IO.println(result);
IO.println(names.stream().map(String::toUpperCase).toList());
}Результат:
[ANNA, OLEG]
[ANNA, OLEG]Функции из этого ответа
- Stream.map() — Преобразует каждый элемент потока.
- Stream.toList() — Собирает элементы потока в неизменяемый список.
- List.replaceAll() — Заменяет каждый элемент списка результатом функции.