filter(), map(), collect() — Stream API Core Operations
These three methods form the most common Stream pipeline in Java. Together, they let you select data, transform it, and gather results in a clean, declarative way.
Source → filter → map → collect
1️⃣ filter() — Selection (Intermediate Operation)
What It Does
filter() selects elements that match a condition.
- Accepts a Predicate<T>
- Returns a new Stream
- Does not modify the source
- Lazy (executes only at terminal operation)
Syntax
stream.filter(predicate)
Example
Listnumbers = List.of(10, 15, 20, 25); List evens = numbers.stream() .filter(n -> n % 2 == 0) .toList();
Output: [10, 20]
Key Points
- Used for conditions
- Can chain multiple filter() calls
- Prefer simple predicates
2️⃣ map() — Transformation (Intermediate Operation)
What It Does
map() transforms each element into another form.
- Accepts a Function<T, R>
- One input → one output
- Returns a new Stream
- Does not change original data
Syntax
stream.map(function)
Example
Listnames = List.of("java", "python"); List upper = names.stream() .map(String::toUpperCase) .toList();
Output: ["JAVA", "PYTHON"]
Common Uses
- Object → field
- Type conversion
- Value transformation
list.stream().map(String::length)
3️⃣ collect() — Aggregation (Terminal Operation)
What It Does
collect() converts a stream into a collection or result.
- Accepts a Collector
- Triggers stream execution
- Ends the stream pipeline
Syntax
stream.collect(collector)
Common Collectors
- Collectors.toList()
- Collectors.toSet()
- Collectors.toMap()
- Collectors.joining()
- Collectors.groupingBy()
- Collectors.counting()
Example
Listresult = numbers.stream() .filter(n -> n > 10) .map(n -> n * 2) .collect(Collectors.toList());
Output: [30, 40, 50]
Combined Example (Most Common Pattern)
Listresult = List.of("java", "spring", "api", "docker") .stream() .filter(s -> s.length() > 3) .map(String::toUpperCase) .collect(Collectors.toList());
- Filter → Transform → Collect
- Clean and readable
filter vs map vs collect (Interview Table)
| Method | Type | Purpose |
|---|---|---|
| filter() | Intermediate | Select elements |
| map() | Intermediate | Transform elements |
| collect() | Terminal | Gather results |
map() vs flatMap() (Quick Contrast)
map() → one-to-one
flatMap() → one-to-many (flattens)
List> data = List.of(List.of(1,2), List.of(3,4)); data.stream() .flatMap(List::stream) .toList(); // [1,2,3,4]
Common Beginner Mistakes
- Using forEach() instead of map()
- Expecting filter() to modify original list
- Forgetting collect() (no execution)
- Writing complex logic inside lambdas
- Using map() for side effects
Best Practices
- Use filter → map → collect pattern
- Keep lambdas short and readable
- Prefer method references
- Use collect() for results, not forEach()
- Avoid mutating external variables
Interview-Ready Answers
Short Answer
filter() selects elements, map() transforms elements, and collect() gathers results.
Detailed Answer
In Java Streams, filter() is an intermediate operation used to select elements based on a condition, map() transforms each element into another form, and collect() is a terminal operation that converts the processed stream into a collection or aggregated result using collectors.
Key Takeaway
filter = select
map = transform
collect = gather
This trio is the backbone of Stream API usage and should feel natural and instinctive in modern Java development.