Differences Between map() and flatMap() in Java

Java 8 introduced the Stream API, which brought a powerful way to process collections using a functional programming style. Two of the most frequently used methods in this API are map() and flatMap().

At first glance, both seem similar — they transform data. But their behavior differs when it comes to dealing with nested structures like List<List<T>>.

In this article, we'll explore the key differences between map() and flatMap() using simple explanations, a comparison table, and complete examples with output.


📘 Quick Summary: map() vs flatMap()

Feature map() flatMap()
Processes Stream of values Stream of stream of values
Functionality Only mapping Performs mapping + flattening
Mapper Output Produces a single value per input Produces multiple values per input
Mapping Type One-to-One mapping One-to-Many mapping
Data Transformation Stream<T>Stream<R> Stream<Stream<T>>Stream<R>
When to Use When mapper produces single output per input When mapper produces multiple outputs per input

Let’s go deeper into each of these differences with examples and real output.

✅ What is map() in Java Stream?

The map() method is used to transform each element of the stream using a mapping function. It applies a function to each value and returns a new stream consisting of the results.

🔧 Syntax:

<R> Stream<R> map(Function<? super T, ? extends R> mapper)

👨‍💻 Example Using map()

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class MapExample {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Amit", "Sneha", "Ravi");

        List<Integer> nameLengths = names.stream()
                .map(String::length) // One-to-one transformation
                .collect(Collectors.toList());

        System.out.println(nameLengths);  // Output: [4, 5, 4]
    }
}

🧠 Explanation:

  • Input stream: "Amit", "Sneha", "Ravi"
  • Output stream: 4, 5, 4 (length of each name)
  • Each input gives exactly one output → One-to-one mapping.

✅ What is flatMap() in Java Stream?

The flatMap() method is used when each element of the stream is mapped to a stream of values, and you want to flatten all nested streams into a single stream.

🔧 Syntax:

<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper)

👨‍💻 Example Using flatMap()

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class FlatMapExample {
    public static void main(String[] args) {
        List<List<String>> nestedList = Arrays.asList(
                Arrays.asList("Amit", "Ankit"),
                Arrays.asList("Sneha", "Sonia"),
                Arrays.asList("Ravi", "Ramesh")
        );

        List<String> flatList = nestedList.stream()
                .flatMap(List::stream)  // Flattens nested structure
                .collect(Collectors.toList());

        System.out.println(flatList);  // Output: [Amit, Ankit, Sneha, Sonia, Ravi, Ramesh]
    }
}

Explanation:

  • Each List<String> becomes a stream.
  • flatMap() flattens all these small streams into a single stream.
  • Output: a flat list of all names.
  • Each input list can contribute multiple values → One-to-many mapping.

⚖️ Difference Explained With Visual Structure

Let’s visualize the difference with structure transformation:

🟦 map() Example:

List<List<String>> → Stream<List<String>> → List<Stream<String>> (Still nested)

🟩 flatMap() Example:

List<List<String>> → Stream<List<String>> → flatMap → Stream<String> → List<String> (Flat)

So with map(), if the mapper function returns a list, you end up with a list of lists. But with flatMap(), you get a flat list.

✅ Use Cases for map() vs flatMap()

Use map() when:

  • You’re transforming each element individually.
  • You get exactly one value back per input.
List<String> names = Arrays.asList("Anil", "Reema", "Kiran");

List<String> upper = names.stream()
    .map(String::toUpperCase)
    .collect(Collectors.toList());
// Output: [ANIL, REEMA, KIRAN]

Use flatMap() when:

  • Each input might return multiple values (like a list or stream).
  • You want to flatten nested data structures.
List<String> phrases = Arrays.asList("Java 8", "Stream API", "flatMap explained");

List<String> words = phrases.stream()
    .flatMap(s -> Arrays.stream(s.split(" ")))
    .collect(Collectors.toList());
// Output: [Java, 8, Stream, API, flatMap, explained]

🧪 Testing the Behavior Side-by-Side

List<String> sentences = Arrays.asList("Hello World", "Java Stream", "flatMap vs map");

// Using map()
List<String[]> mapped = sentences.stream()
    .map(s -> s.split(" "))
    .collect(Collectors.toList());

// Using flatMap()
List<String> flatMapped = sentences.stream()
    .flatMap(s -> Arrays.stream(s.split(" ")))
    .collect(Collectors.toList());

System.out.println("Mapped Size: " + mapped.size());       // Output: 3 (List of arrays)
System.out.println("FlatMapped Size: " + flatMapped.size()); // Output: 6 (All words)

🧾 Summary Table Revisited

Feature map() flatMap()
Processes Stream of values Stream of stream of values
Functionality Only mapping Mapping + flattening
Mapper Output One value per input Multiple values per input
Mapping Type One-to-One One-to-Many
Transformation Stream<T>Stream<R> Stream<Stream<T>>Stream<R>
Use When Each input maps to a single result Each input maps to a list or stream of results
Example List<String> → uppercase list List<List<String>> → flat list of strings

Final Thoughts

Both map() and flatMap() are essential tools in the Java Stream toolbox. While map() is perfect for straightforward transformations, flatMap() shines when you're dealing with nested data structures or multiple values per element.

  • Use map() when you know you're doing one-to-one conversions.
  • Use flatMap() when each input element may return multiple values (e.g., splitting, nested lists, complex structures).

Understanding the difference between these two helps you write cleaner, more efficient, and more expressive Java code.

Comments

Spring Boot 3 Paid Course Published for Free
on my Java Guides YouTube Channel

Subscribe to my YouTube Channel (165K+ subscribers):
Java Guides Channel

Top 10 My Udemy Courses with Huge Discount:
Udemy Courses - Ramesh Fadatare