В разработке иногда встречается задача "выпрямления" вложенных списков, то есть создания одного плоского списка из списка списков или списка массивов. В стримах за это отвечает метод flatMap()
, который работает как показано в коде ниже.
var listOfLists = List.of(
List.of(1, 2, 3),
List.of(4, 5, 6),
List.of(7, 8, 9)
);
// Stream<List<Integer>> to Stream<Integer>
var flattenedList = listOfLists.stream()
.flatMap(List::stream)
.toList();
System.out.println(flattenedList); // Output: [1, 2, 3, 4, 5, 6, 7, 8, 9]
flatMap()
работает как отображение map
, которое применяет к каждому элементу стрима переданную лямбду. Эта лямбда преобразует каждый элемент, в нашем случае список чисел, в стрим. Когда все элементы преобразованы в стримы, выполняется вторая часть flatMap
, стримы объединяются в один.
Особенно часто flatMap()
встречается в работе с файловой системой при чтении списка файлов и директорий, а так же при работе с содержимым файлов. Ниже мы разберем подобный пример, но если он вам покажется слишком сложным, то не переживайте, просто пропустите его и вернитесь позже.
Для примера посчитаем частоту слов в файле. Для этого прочитаем файл с помощью File.lines()
, этот метод возвращает стрим состоящий из строк файла. Именно здесь нам понадобится flatMap()
для обработки каждой строки.
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.stream.Collectors;
try (var lines = Files.lines(Path.of("README.md"))) {
var res = lines.flatMap(line -> Arrays.stream(line.trim().split("\\s+")))
.map(String::toLowerCase)
.collect(Collectors.groupingBy(word -> word, Collectors.counting()));
System.out.println(res);
}
Это маленькая программа, но в ней происходит очень много всего сразу. Разберем ее построчно.
- Конструкция
try
нужна для работы с такими ресурсами как файлы, она никак не влияет на нашу программу, поэтому не обращаем на нее внимание, она изучается позже. - Читается файл README.md построчно в переменную
lines
. МетодFiles.lines
возвращаетStream<String>
. - Вызывается
flatMap()
, который преобразует набор строк в плоский список слов. Для этого внутри лямбды каждая строка разбивается на слова. Получившийся массив преобразуется в стрим с помощьюArrays.stream
. - Все слова приводятся к нижнему регистру, на случай если они были написаны по-разному. Это называется нормализацией данных.
- Выполняется группировка слов по частоте.
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.