Pipeline Anatomy
The three parts of every pipeline, and why nothing runs without a terminal op.
Open this lesson in the learning hubKey points
- Three parts: a source, zero or more intermediate ops, and exactly one terminal op.
- Intermediate ops return a Stream.
filter,map,sorted,limitonly record your intent. - Terminal ops return something that is not a Stream.
toList,count,forEach,reducefire the whole chain. - No terminal op means no work at all. This is the number one stream surprise.
- After the terminal op the stream is spent. Build a fresh one from the source.
Example
import java.util.*;
import java.util.stream.*;
public class Main {
public static void main(String[] args) {
List<String> words = List.of("stream", "lazy", "terminal", "op");
Stream<String> pipeline = words.stream() // 1. source
.filter(w -> w.length() > 2) // 2. intermediate
.map(String::toUpperCase); // 3. still intermediate
System.out.println("Built the pipeline. Nothing has run.");
List<String> result = pipeline.toList(); // 4. terminal -> now it runs
System.out.println("toList : " + result);
// Terminal ops come in three flavours: a value, a container, or nothing.
System.out.println("count : " + words.stream().filter(w -> w.contains("a")).count());
System.out.println("anyMatch : " + words.stream().anyMatch(w -> w.length() == 2));
words.stream().limit(2).forEach(w -> System.out.println("forEach : " + w));
}
}
Nothing happens until the terminal op asks for a result.
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.