This post will discuss the difference between map() and flatMap() methods of Stream class in Java.

1. Signature

The prototype of the Stream.map() is:

/**
* @param The element type of the new stream
* @param mapper a non-interfering, stateless method to apply to each element
* @return the new stream
*/
<R> Stream<R> map(Function<? super T, ? extends R> mapper);

 
The prototype of the Stream.flatMap() is:

/**
* @param The element type of the new stream
* @param mapper a non-interfering, stateless method to apply to each
* element which produces a stream of new values
* @return the new stream
*/
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);

2. Definition

Both map() and flatMap() takes a mapping function, which is applied to each element of a Stream<T>, and returns a Stream<R>. The only difference is that the mapping method in the case of flatMap() produces a stream of new values, whereas for map(), it produces a single value for each input element.

Arrays.stream(), List.stream(), etc, are commonly used mapping method for flatMap(). Since the mapping method for flatMap() returns another stream, we should get a stream of streams. However, flatMap() has the effect of replacing each generated stream with the contents of that stream. In other words, all the separate streams that are generated by the method get flattened into one single stream.[1]

3. How to use map() method

Since map() produce a stream consisting of the results of applying the given method to the elements of the input Stream, it is often used for converting the stream of one type to a stream of another type. For instance, here’s how we can convert list of Character to list of Integer (assuming valid input).

 
The above code can be further shortened with lambdas, as shown below:

 
Here’s how we can convert list of Integer to a list of Character.

 
We can also do this with a single call to map() method, as shown below:

4. Why do we need flatMap()?

Suppose we have a list of List<Integer> and we need a single list of Integer containing elements of all the member lists. This can be done as follows:

Download  Run Code

Output:

Before flattening: [[1, 2, 3], [4, 5], [6, 7, 8]]
After flattening : [1, 2, 3, 4, 5, 6, 7, 8]

 
This is equivalent to:

Download  Run Code

Output:

Before flattening: [[1, 2, 3], [4, 5], [6, 7, 8]]
After flattening : [1, 2, 3, 4, 5, 6, 7, 8]

That’s all about differences between the map() and flatMap() in Java.