← Back to Home

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

List numbers = 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

List names = 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

List result =
    numbers.stream()
           .filter(n -> n > 10)
           .map(n -> n * 2)
           .collect(Collectors.toList());
          

Output: [30, 40, 50]

Combined Example (Most Common Pattern)

List result =
    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.