How does short-circuiting work in Stream?
Sink has a cancellationRequested() method:
🟢 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 firsttrueallMatch()— stops at the firstfalsenoneMatch()— stops at the firsttruefindFirst()/findAny()— stops at the first elementlimit(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
trueafter 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 tofindFirst()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]]