Question 24 · Section 8

How does short-circuiting work in Stream?

Sink has a cancellationRequested() method:

Language versions: English Russian Ukrainian

🟢 Junior Level

Short-circuiting — the stream stops as soon as the result is determined, without processing the remaining elements.

Analogy: like && in Java: false && expensiveCheck()expensiveCheck() will not execute because the result is already determined (false). Analogous to break in a loop.

Terminal operations with short-circuiting:

  • anyMatch() — stops at the first true
  • allMatch() — stops at the first false
  • noneMatch() — stops at the first true
  • findFirst() / findAny() — stops at the first element
  • limit(n) — stops after n elements
// Will stop after the first match found
boolean hasAdult = persons.stream()
    .anyMatch(p -> p.getAge() >= 18);

// Will take only the first 5
List<String> first5 = list.stream().limit(5).collect(toList());

🟡 Middle Level

Internal mechanism: cancellationRequested flag

Sink has a cancellationRequested() method:

  • Terminal operations set it to true after finding the result
  • Intermediate operations check the flag before requesting the next element
  • Spliterator stops data traversal

Types of short-circuiting

Java 9+: count() on SIZED sources (ArrayList, array) is optimized — returns the size without running through the pipeline. This means filter/map BEFORE count() may NOT execute!

Terminal: Stop the entire pipeline when the condition is met (anyMatch, findFirst)

Intermediate: Limit the data volume (limit(n)) — turns an infinite stream into a finite one

Working with infinite streams

Stream.iterate(0, n -> n + 1)  // Infinite
    .filter(n -> n % 2 == 0)
    .limit(10)                  // Limits
    .collect(toList());         // Completes successfully

Important: If you swap filter and limit incorrectly — you can get an infinite loop.

🔴 Senior Level

Concurrency and Short-circuiting

In parallel streams, it works less efficiently:

  • Multiple threads may continue computing after the result is found
  • limit() requires complex coordination (buffering from different threads)
  • A parallel stream can become slower than sequential

Wait Cost

In distributed systems, findAny() is preferable to findFirst() — it returns the result from the “fastest” thread, without waiting for elements in queue order.

Infinite loop detection

If CPU is at 100% and the stream does not terminate — check the short-circuit conditions. Add peek() before the short-circuit operation — you will see how many elements were actually checked.

Short-circuit vs Loops

Short-circuiting in streams works as efficiently as break or return in a regular for loop.


🎯 Interview Cheat Sheet

Must know:

  • Short-circuiting — the stream stops as soon as the result is determined, without processing remaining elements
  • Terminal short-circuit: anyMatch, allMatch, noneMatch, findFirst, findAny
  • Intermediate short-circuit: limit(n) — turns an infinite stream into a finite one
  • Mechanism: cancellationRequested() flag in Sink, Spliterator stops traversal
  • In parallelStream, short-circuit works less efficiently — multiple threads may continue computing
  • findAny() is preferable to findFirst() in parallel streams — does not wait for the “leftmost” element
  • anyMatch/limit — key tools for working with infinite streams
  • Java 9+: count() on SIZED sources is optimized — filter/map BEFORE count() may NOT execute

Frequent follow-up questions:

  • How does short-circuiting work internally? — The terminal operation sets cancellationRequested = true, the Spliterator stops requesting elements.
  • Why is findAny faster than findFirst in parallelStream? — findFirst requires thread coordination for order guarantee; findAny returns the result from the fastest thread.
  • Can limit() work with an infinite stream? — Yes, limit(n) is the only way to terminate an infinite stream, but it must be placed before heavy operations.
  • Why can parallelStream become slower with short-circuit? — Multiple workers continue working after the result is found, overhead from task cancellation.

Red flags (DO NOT say):

  • “Short-circuit processes all elements” — incorrect, that is the whole point of short-circuiting
  • “findFirst and findAny are the same in parallelStream” — incorrect, findFirst is expensive due to coordination
  • “limit() after sorted() is a good idea” — incorrect, sorting the entire set before limiting is excessive
  • “parallelStream is always faster for short-circuit” — incorrect, it can be slower due to coordination

Related topics:

  • [[21. What is lazy evaluation in Stream]]
  • [[22. When does Stream operation execution begin]]
  • [[25. What are anyMatch(), allMatch(), noneMatch() operations]]
  • [[26. What do findFirst() and findAny() operations do]]