How does the Stream API work? Explain lazy evaluation, intermediate vs terminal operations, and show a grouping example.
Show the explanation
A stream is a pipeline over a data source (a collection, an array, a file, a range). It does not store data and does not change the source.
- Intermediate operations —
filter,map,sorted,distinct,limit,flatMap— return a new stream and are lazy: nothing runs yet. - A terminal operation —
collect,forEach,count,reduce,anyMatch,toList()— triggers the whole pipeline, element by element. A stream can be consumed only once.
record Order(String city, int amount) {}
List<Order> orders = List.of(new Order("Pune", 300), new Order("Delhi", 120), new Order("Pune", 80));
int bigTotal = orders.stream()
.filter(o -> o.amount() >= 100)
.mapToInt(Order::amount)
.sum(); // 420
Map<String, Integer> byCity = orders.stream()
.collect(Collectors.groupingBy(Order::city, TreeMap::new,
Collectors.summingInt(Order::amount))); // {Delhi=120, Pune=380}Because of laziness, limit and anyMatch can stop early (short-circuit). Keep lambdas free of side effects, and remember that parallelStream() only helps for large, CPU-heavy work — it is not a free speed-up.
Original UniCircle question. Last reviewed 22 Oct 2026.
