Методы Stream<T>
Stream — ленивый одноразовый pipeline, а не коллекция. Источник обходится после terminal operation.
Промежуточные операции
| Операция | Роль |
|---|---|
filter | оставить элементы по predicate |
map / flatMap | преобразовать / развернуть вложенные источники |
peek | наблюдение, главным образом диагностика |
distinct | убрать дубликаты по equals/hashCode |
sorted | отсортировать |
limit / skip | ограничить/пропустить |
takeWhile / dropWhile | взять/отбросить начальный префикс |
distinct и sorted — stateful: им нужно помнить элементы. На ordered stream dropWhile отбрасывает только самый длинный начальный префикс, а не все совпавшие элементы.
Терминальные операции
| Операция | Результат |
|---|---|
toList, collect | материализовать результат |
reduce | свернуть значения |
count, min, max | агрегировать |
findFirst, findAny | найти элемент |
anyMatch, allMatch, noneMatch | short-circuit проверка |
forEach, forEachOrdered | выполнить действие |
Map<Status, Long> countByStatus = tasks.stream()
.filter(Task::isVisible)
.collect(Collectors.groupingBy(
Task::status,
() -> new EnumMap<>(Status.class),
Collectors.counting()
));Stream.toList() возвращает unmodifiable list. Collectors.toList() не обещает конкретный тип и mutability — если нужна изменяемость, указать supplier явно.
List<String> mutable = stream.collect(
Collectors.toCollection(ArrayList::new)
);Нюансы
allMatchиnoneMatchна пустом stream возвращаютtrue,anyMatch—false;findFirstсохраняет encounter order,findAnyможет дать больше свободы parallel pipeline;Stream.concat(a, b)— static-операция создания нового stream; его закрытие закрывает оба исходных;- mutable side effects в
map/filterломают рассуждение и parallel execution; - бесконечный stream требует short-circuit/limit для завершения.
На собеседовании
Чем intermediate отличается от terminal? Первая строит ленивый pipeline, вторая запускает обход.
Почему peek может не выполниться для каждого элемента? Pipeline ленив и может short-circuit/оптимизировать обход.
Что вернёт allMatch для пустого stream? true.
Можно ли повторно вызвать terminal operation? Нет, stream уже consumed.
Гарантирует ли toList() изменяемый список? Нет, Stream.toList() возвращает unmodifiable list.
Связано: Промежуточные операции, Терминальные операции, BaseStream.