Interview Prep Zoneby CuriouserLabs

Question 1 of 5 · senior level

How does a stream pipeline actually execute? Explain laziness, short-circuiting and loop fusion.

🎤 Say this first

Intermediate operations (filter, map) build a linked pipeline of stages and execute nothing; only the terminal operation pulls data. Elements then flow one at a time through the whole pipeline (depth-first), not stage-by-stage over the collection — so operations are fused into one pass and short-circuiting terminals (findFirst, anyMatch, limit) can stop the source early. This is why streams handle infinite generators and why side effects in intermediate ops are undefined behavior territory.

The full picture

🎬 Lazy stream pipeline with short-circuit

1 / 4
source: List123456filtern % 2 == 0mapn → n²findFirst()terminal · pullsnothing runs yet — just a linked recipe 📜One element travels the full pipeline at a time (depth-first), enabling short-circuit terminals.

stream().filter(n -> n % 2 == 0).map(n -> n * n).findFirst() — building the pipeline executes NOTHING. Intermediate ops are lazy; they just link stages together.

One element at a time, whole pipeline, stop at first match.
  • Spliterator drives the source; each stage wraps the next stage's Sink — a terminal op assembles the chain then pushes/pulls elements through it.
  • Stateless vs stateful ops: map/filter fuse cleanly; sorted/distinct must buffer (a barrier) — a sorted() in the middle quietly makes 'lazy' mostly moot up to that point.
  • Single-use: a stream is a one-shot pipeline, not a data structure; reusing it throws IllegalStateException.
  • Don't mutate the source mid-pipeline; interference is checked only best-effort.

🔄 Likely follow-up questions

  • Why does Stream.iterate(0, i -> i + 1).filter(...).findFirst() terminate?
  • What makes limit() expensive in parallel pipelines? (encounter order)
  • When does count() skip executing your pipeline entirely?