Ответ 1
Из javadoc пакета stream
:
Почти во всех случаях операторы терминала нетерпеливы, завершая их обход источника данных и обработка трубопровода до возвращение. Только операции терминала
iterator()
иspliterator()
не; они предоставляются как "люк-побег" для обеспечения произвольного контролируемые клиентом трассы трубопровода в том случае, если существующие операций недостаточно для выполнения задачи.
Это означает, что в большинстве случаев обход потока завершается, когда возвращается операция терминала, но не в случае iterator()
и spliterator()
: с помощью одной из этих операций терминала Iterator
или Spliterator
, но конвейер по-прежнему "открыт" и будет обрабатываться по мере запроса элементов через итератор. Таким образом, обработка потока становится ленивой, поскольку операции с потоком выполняются только в том случае, если запрашивается следующий элемент.
Iterator<Person> iterator = persons
.stream()
.filter(p -> !p.getName().equals("Mike Tyson"))
.iterator();
После вызова метода iterator()
поток "завершается": вы не можете использовать больше методов. Но вы можете получить доступ к элементам потока, вызвав метод next()
возвращенного итератора, и поток начнет обрабатываться только в первый раз, когда вы это сделаете. И это верно, только если используется операция терминала iterator()
или spliterator()
.