I was reading
Except for the escape-hatch operations iterator() and spliterator(),
execution begins when the terminal operation is invoked, and ends when
the terminal operation completes
From the javadoc of
In almost all cases, terminal operations are eager, completing their traversal of the data source and processing of the pipeline before returning. Only the terminal operations iterator() and spliterator() are not; these are provided as an "escape hatch" to enable arbitrary client-controlled pipeline traversals in the event that the existing operations are not sufficient to the task.
Which means, that in most of the cases the stream traversal is complete when a terminal operation returns, but not in case of
spliterator(): by using one of these terminal oparation an
Iterator or a
Spliterator is returned, but the pipeline is still "open" and it will be processed as the elements are requested through the iterator. This way the stream processing becomes lazy, because the operations on the stream are only executed if the next element is requested.
Iterator<Person> iterator = persons.stream() .filter(p -> !p.getName().equals("Mike Tyson")).iterator();
iterator() method is called, the stream is "terminated": you cannot chain more methods. But you can access the elements of the stream by calling
next() on the returned iterator and the stream will started to be processed only at the first time you do this. And this is true only if the
iterator() or the
spliterator() terminal operation is used.