Difference between map() and flatMap() in Java
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
* @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
* @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).
|
1 2 3 |
Stream.of('1', '2', '3') // Stream<Character> .map(String::valueOf) // Stream<String> .map(Integer::parseInt); // Stream<Integer> |
The above code can be further shortened with lambdas, as shown below:
|
1 2 |
Stream.of('1', '2', '3') // Stream<Character> .map(ch -> Integer.parseInt(ch.toString())); // Stream<Integer> |
Here’s how we can convert list of Integer to a list of Character.
|
1 2 3 |
Arrays.asList(1, 2, 3).stream() // Stream<Integer> .map(String::valueOf) // Stream<String> .map(s -> s.charAt(0)); // Stream<Character> |
We can also do this with a single call to map() method, as shown below:
|
1 2 |
Arrays.asList(1, 2, 3).stream() // Stream<Integer> .map(s -> String.valueOf(s).charAt(0)); // Stream<Character> |
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:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; class Main { public static void main(String[] args) { List<Integer> a = Arrays.asList(1, 2, 3); List<Integer> b = Arrays.asList(4, 5); List<Integer> c = Arrays.asList(6, 7, 8); List<List<Integer>> listOfListOfInts = Arrays.asList(a, b, c); System.out.println("Before flattening: " + listOfListOfInts); List<Integer> listofInts = listOfListOfInts.stream() .flatMap(list -> list.stream()) .collect(Collectors.toList()); System.out.println("After flattening : " + listofInts); } } |
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:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
import java.util.ArrayList; import java.util.Arrays; import java.util.List; class Main { public static void main(String[] args) { List<Integer> a = Arrays.asList(1, 2, 3); List<Integer> b = Arrays.asList(4, 5); List<Integer> c = Arrays.asList(6, 7, 8); List<List<Integer>> listOfListOfInts = Arrays.asList(a, b, c); System.out.println("Before flattening: " + listOfListOfInts); List<Integer> listofInts = new ArrayList<>(); for (List<Integer> list : listOfListOfInts) { for (Integer integer : list) { listofInts.add(integer); } } System.out.println("After flattening : " + listofInts); } } |
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.
Thanks for reading.
To share your code in the comments, please use our online compiler that supports C, C++, Java, Python, JavaScript, C#, PHP, and many more popular programming languages.
Like us? Refer us to your friends and support our growth. Happy coding :)