Laziness and Short-Circuiting
Why streams do the minimum work possible, and how that makes infinite sources safe.
Open this lesson in the learning hubKey points
- Elements are pulled, not pushed. One element runs the whole chain before the next one starts.
- So
filterandmapfuse into a single walk. No intermediate lists are ever built. - Short-circuit ops stop as soon as the answer is known:
findFirst,findAny,anyMatch,allMatch,limit. - Laziness is what makes infinite sources usable.
Stream.iterate(...).limit(4)terminates. peekis a debugging window, not a work step. It may never run if the terminal op skips the traversal.
Example
import java.util.*;
import java.util.stream.*;
public class Main {
public static void main(String[] args) {
List<String> words = List.of("alpha", "beta", "gamma", "delta");
// One element travels the whole pipeline before the next one starts.
System.out.println("-- one element at a time --");
String hit = words.stream()
.peek(w -> System.out.println(" filter sees " + w))
.filter(w -> w.length() == 4)
.peek(w -> System.out.println(" map sees " + w))
.map(String::toUpperCase)
.findFirst()
.orElse("none");
System.out.println("hit = " + hit + " (gamma and delta were never touched)");
// Short-circuiting lets you consume an infinite source safely.
System.out.println("-- infinite source --");
System.out.println("odd squares : " + Stream.iterate(1, i -> i + 1)
.map(i -> i * i)
.filter(i -> i % 2 == 1)
.limit(4)
.toList());
System.out.println("anyMatch : " + words.stream().anyMatch(w -> w.startsWith("g")));
System.out.println("allMatch : " + words.stream().allMatch(w -> w.length() > 3));
}
}
Streams do the least work that still answers your question.
This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Streams course, and every lesson in it is listed on the Streams contents page.