Java Stream map() vs. flatMap() with Examples

The Java 8 Stream interface contains the map() and flatMap() methods that process the elements of the current Stream and return a new Stream. Both methods are intermediate stream operations and serve distinct purposes.

In this article, we’ll explore the differences between these operations and discuss when to use one over the other.

1. Stream map(): One-to-One Operation

The map() operation is used to transform each element of a stream into another object using a given function. It returns a new stream containing the transformed elements in the same order as the original stream.

This transformation is one-to-one, meaning each input element produces exactly one output element. So, if there are N elements in the stream, the map() operation will produce a new stream of N elements.

List<String> listOfStrings = Arrays.asList("1", "2", "3", "4", "5");
 
List<Integer> listOfIntegers = listOfStrings.stream()
                                .map(Integer::valueOf)
                                .toList();
 
System.out.println(listOfIntegers);   //[1, 2, 3, 4, 5]

2. Stream flatMap(): One-to-Many Operation

The flatMap() operation is used when each element in the stream is transformed into multiple elements, often in the form of another collection or stream. The resulting elements are then flattened into a single stream.

This transformation is one-to-many, meaning an input element produces multiple output elements, later all flattened into a single Stream.

In more simple words, the flatMap() operation is a two-step process i.e. map() + flattening. In a broader sense, it helps convert Collection<Collection<Item>> to Collection<Item>.

List<List<Integer>> listOfLists = Arrays.asList(
  Arrays.asList(1, 2, 3),
  Arrays.asList(4, 5),
  Arrays.asList(6, 7, 8)
);

List<Integer> flattenedList = listOfLists.stream()
      .flatMap(list -> list.stream())
      .toList();

System.out.println(flattenedList);    //[1, 2, 3, 4, 5, 6, 7, 8]

3. Differences between Stream map() and flatMap()

The main difference between map() and flatMap() is that map() only transforms the elements of this Stream, but flatMap() transforms and flattens, both.

flatMap() = map() + Flattening

Let’s compare these two operations using a table:

Aspectmap()flatMap()
TransformationOne-to-one transformationOne-to-many transformation
Input to Output1 input -> 1 output1 input -> n outputs (flattened)
Output SequencePreserves input sequenceFlattens output
When to UseModify values, Extract propertiesSplitting string, Combining nested collections
Common UsageNormal data transformationsHandling nested structures

4. Usage of map() vs flatMap()

Use Stream.map() when we need to transform each element individually and the output has a one-to-one relationship with the input.

For example, we can write a program to find the date of birth of all employees in a stream of employees. For each employee in the Stream, we will have one date of birth as the output value extracted from the input Employee object.

List<Employee> employees = ...;

List<LocalDate> datesOfBirth = employees.stream()
    .map(Employee::getDateOfBirth)
    .collect(Collectors.toList());

Use flatMap() when we need to transform each element into multiple elements, such as when dealing with nested collections.

For example, we may write a program to find all district words from all lines in a text file. The following example:

  • Reads a text file using Files.lines() to obtain a stream of lines.
  • The flatMap() operation transforms each line into a new Stream of words. This is the one-to-many transformation.
  • The words from all the streams are collected into a single Set and it is the flattening operation.
String filePath = "path/to/your/textfile.txt";

Stream<String> lines = Files.lines(Paths.get(filePath));

Set<String> distinctWords = lines
  .flatMap(line -> Arrays.stream(line.split("\\s+")))
  .collect(Collectors.toSet());

System.out.println("Distinct words in the file: " + distinctWords);

5. Conclusion

As discussed above, map() and flatMap(), both operations serve distinct purposes and are instrumental in streamlining data processing tasks. To keep things simpler, always remember that the map() operation is designed for one-to-one transformations, and conversely, the flatMap() operation handles one-to-many transformations.

Happy Learning !!

Comments

Subscribe
Notify of
guest
4 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.