WalkthroughDifficulty: Intermediate2 min

Stream Laziness Walkthrough: One Element at a Time Through the Chain

A thousand numbers, and a pipeline that stops after touching three hundred of them.

A stream does not run each step over the whole source before the next. The terminal operation pulls one element at a time through the entire chain, and stops pulling as soon as it has its answer. A pipeline that prints each element it touches shows this: a thousand numbers, a filter, a map and a findFirst.

java
Optional<String> first = numbers.stream()
        .peek(n -> System.out.println("testing " + n))
        .filter(n -> n % 300 == 0)
        .map(n -> "found " + n)
        .findFirst();

What the pipeline does, element by element

findFirst asks for one element

The terminal operation drives everything. It does not ask the source for a thousand elements. It asks for one, and the whole chain above it runs for that one element before the second is fetched.

Element 1 goes through the whole chain

text
testing 1

peek prints, filter rejects it, and map is never reached for this element. A rejected element stops where it was rejected.

Elements 2 to 299 do the same

Each one is fetched, printed and rejected in turn. Nothing accumulates: at no point is there a list of filtered elements waiting for map.

Element 300 passes the filter and reaches map

text
testing 300

This is the only element map is ever called on. The transformation runs once, not three hundred times and not a thousand.

findFirst has what it needs and stops

Elements 301 to 1000 are never fetched and never printed: three hundred peek calls, three hundred filter calls and one map call, for a source of a thousand.

The run to remember: the terminal operation pulls, one element at a time, through the whole chain. That is why findFirst, anyMatch and limit can stop early, and why putting filter before map does less work than the other way round.

One kind of step breaks the pattern. sorted cannot hand on its first element until it has seen all of them, so a sorted in the chain pulls the entire source through the steps above it before anything reaches the steps below.