peek: Watching a Pipeline Run
See what each stage receives without changing the data, and learn where peek lies to you.
Open this lesson in the learning hubKey points
peekis an intermediate op that hands you every element on its way past and then passes it along unchanged.- Use it to answer "what reached my filter" and "how many elements got that far". It is a window, not a work step.
- It is not guaranteed to run.
count()on a sized source skips the whole traversal, so the peek never fires. - Never mutate anything from a peek. In parallel it runs on several threads with no ordering at all.
- For anything long lived, promote the logic to a named method and log inside it. That is debuggable and testable.
Example
import java.util.*;
public class Main {
public static void main(String[] args) {
List<String> words = List.of("alpha", "beta", "gamma", "delta");
List<String> out = words.stream()
.peek(w -> System.out.println("source -> " + w))
.filter(w -> w.length() == 5)
.peek(w -> System.out.println(" kept -> " + w))
.map(String::toUpperCase)
.toList();
System.out.println("result : " + out);
// peek is not guaranteed to run: count() can skip a sized pipeline entirely.
long n = words.stream().peek(w -> System.out.println("counted " + w)).count();
System.out.println("count : " + n + " (the peek above may never print)");
// A named predicate is easier to debug than a peek.
System.out.println("named : " + words.stream().filter(Main::isFive).toList());
}
static boolean isFive(String w) {
boolean ok = w.length() == 5;
System.out.println(" isFive(" + w + ") = " + ok);
return ok;
}
}
peek shows you the traffic; it must never be part of the work.
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.