Intermediate
The Stream API
📂 Phase 5: Advanced Java — Streams, Lambda, Multithreading, DB (Days 22–26) · JavaA Stream is a sequence of elements that supports functional-style, declarative operations — filtering, transforming, and aggregating data without writing manual loops. Streams build directly on lambdas and functional interfaces from Day 22.
Creating a Stream
List names = Arrays.asList("Alice", "Bob", "Charlie", "Dave");
Stream nameStream = names.stream();
Intermediate Operations — filter() and map()
Intermediate operations return a new stream and are lazy — nothing actually executes until a terminal operation is called.
List result = names.stream()
.filter(name -> name.length() > 3) // keep names longer than 3 chars
.map(String::toUpperCase) // transform each to uppercase
.collect(Collectors.toList());
System.out.println(result); // [ALICE, CHARLIE, DAVE]
Terminal Operations — Where Execution Actually Happens
| Operation | Purpose |
|---|---|
| collect() | Gathers stream results into a List, Set, or Map |
| forEach() | Performs an action on each element |
| count() | Returns the number of elements |
| reduce() | Combines elements into a single result |
The reduce() Operation
List numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream()
.reduce(0, (a, b) -> a + b);
System.out.println(sum); // 15
Chaining Multiple Operations
List scores = Arrays.asList(55, 90, 42, 78, 88, 30);
long passCount = scores.stream()
.filter(s -> s >= 50)
.count();
System.out.println(passCount); // 4
map() vs flatMap()
map() transforms each element one-to-one. flatMap() is used when each element itself produces a stream (e.g., a list of lists), flattening the nested structure into one stream.
Interview tip: Streams do NOT modify the original collection — they produce a new result. A common mistake is expecting names.stream().filter(...) to change the original names list; it never does, since streams are designed around immutability and functional purity.