Java 8 Stream.flatMap() method is used to flatten a Stream of collections to a Stream of objects. During the flattening operation, the objects from all the collections in the original Stream are combined into a single collection
Stream<Collection<Item>> —-> flatMap() —-> Stream<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()) // Flattening step
.toList();
//Prints [1, 2, 3, 4, 5, 6, 7, 8]
System.out.println("Flattened list: " + flattenedList);
1. What is Flattening?
Imagine we have a bunch of boxes, and each box contains some items. Now, we want to take out all those items from the boxes and put them in a single box. That’s what flatMap()
does with a stream. It takes objects from different collections in this stream A and puts all objects in a new Stream B.
In layman’s terms, flattening is referred to as merging multiple collections/arrays into one. Consider the following example.
In this example, we have an array of 3 arrays. After the flattening effect, we will have one result array with all the items from the 3 arrays.
Before flattening : [[1, 2, 3], [4, 5], [6, 7, 8]]
After flattening : [1, 2, 3, 4, 5, 6, 7, 8]
In the following example, lines
is a stream of lines in the file. Each line consists of multiple words. The words
stream is a fattened version of all streams into a single stream – consisting of all the words in all the lines.
Path path = ...; //File Path
Stream<String> lines = Files.lines(path, StandardCharsets.UTF_8);
Stream<String> words = lines.flatMap(line -> Stream.of(line.split(" +")));
2. Stream flatMap() Method
2.1. Method Syntax
The stream flatMap()
method has the following syntax.
<R> Stream<R> flatMap(Function<? super T,? extends Stream<? extends R>> mapper)
R
represents the element type of the new stream.mapper
is a non-interfering, stateless function to apply to each element which produces a stream of new values.- The method returns a new stream of objects of type
R
.
2.2. Features
- The
flatMap()
is an intermediate operation and returns a new Stream. - It returns a Stream consisting of the results of replacing each element of the given stream with the contents of a mapped stream produced by applying the provided mapping function to each element.
- The
mapper
function used for transformation inflatMap()
is a stateless function and returns only a stream of new values. - Each mapped Stream is closed after its contents have been placed into new Stream.
flatMap()
operation flattens the stream; opposite tomap()
operation which does not apply flattening.
3. Stream flatMap() Examples
Example 1: Converting Nested Lists into a Single List
Java 8 example of Stream.flatMap() function to get a single List
containing all elements from a list of lists.
This program uses flatMap()
operation to convert List<List<Integer>>
to List<Integer>
.
List<Integer> list1 = Arrays.asList(1,2,3);
List<Integer> list2 = Arrays.asList(4,5,6);
List<Integer> list3 = Arrays.asList(7,8,9);
List<List<Integer>> listOfLists = Arrays.asList(list1, list2, list3);
List<Integer> listOfAllIntegers = listOfLists.stream()
.flatMap(x -> x.stream())
.collect(Collectors.toList());
System.out.println(listOfAllIntegers);
Program output.
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Example 2: Collecting Nested Arrays into a Single List
Java 8 example of Stream.flatMap() function to get a single List
containing all elements from an array of arrays.
String[][] dataArray = new String[][]{{"a", "b"},
{"c", "d"}, {"e", "f"}, {"g", "h"}};
List<String> listOfAllChars = Arrays.stream(dataArray)
.flatMap(x -> Arrays.stream(x))
.collect(Collectors.toList());
System.out.println(listOfAllChars);
Program output.
[a, b, c, d, e, f, g, h]
4. Flattening with IntStream, LongStream and DoubleStream
Stream interface has three more similar methods which produce IntStream
, LongStream
and DoubleStream
respectively that are super helpful if the flattened stream consists only of numeric values such as long, int or doubles.
IntStream flatMapToInt(Function<? super T,? extends IntStream> mapper)
LongStream flatMapToLong(Function<? super T,? extends LongStream> mapper)
DoubleStream flatMapToDouble(Function<? super T,? extends DoubleStream> mapper)
These classes provide convenient methods to perform mathematical operations on all the elements of the Stream, which is often required.
Consider the following example. We have a list of the list of numbers, and we want the sum of all the numbers.
List<List<Integer>> listOfLists = Arrays.asList(
Arrays.asList(1, 2, 3),
Arrays.asList(4, 5),
Arrays.asList(6, 7, 8)
);
int sum = listOfLists.stream()
.flatMap(list -> list.stream()) // Flatten the list of lists
.mapToInt(Integer::intValue) // Convert to IntStream
.sum(); // Calculate the sum
System.out.println("Sum of all numbers: " + sum); //36
Drop me your questions related to Stream flatMap() example in Java Stream API.
Happy Learning !!
Comments