Ответ
Промежуточные операции (filter, map, sorted и т.д.) выполняются лениво (lazy). Это означает, что они не производят немедленных вычислений, а лишь конструируют новый Stream, описывающий конвейер операций.
Выполнение происходит только при вызове терминальной операции (collect, forEach, reduce, count и др.). При этом обработка элементов происходит поэлементно и последовательно по цепочке.
Пример, демонстрирующий ленивое выполнение:
List<String> letters = List.of("a", "b", "c", "d");
Stream<String> stream = letters.stream()
.peek(s -> System.out.println("Источник: " + s)) // Промежуточная
.filter(s -> {
System.out.println(" filter: " + s); // Промежуточная
return s.compareTo("b") > 0;
})
.map(s -> {
System.out.println(" map: " + s); // Промежуточная
return s.toUpperCase();
});
// На этом этапе НИЧЕГО не выведется — поток не активирован.
System.out.println("--- Вызов терминальной операции ---");
List<String> result = stream.collect(Collectors.toList()); // Активация
Вывод программы:
--- Вызов терминальной операции ---
Источник: a
filter: a
Источник: b
filter: b
Источник: c
filter: c
map: c
Источник: d
filter: d
map: d
Ключевой вывод: Элементы обрабатываются один за другим, проходя весь конвейер операций, и только по требованию терминального метода.