Flattening Streams
When you use map( ), a function is applied to each element, and the result is a new stream with the results. Now, suppose you have a function that returns not just one value but a stream of values:
Suppose you map the stringToInStream method on a Stream of Strings:
Each values are printed by nested forEach( ) method. The strin.forEach( ) method calls the forEach() method of each stream, because strin is reference to Stream of Stream.
The flatMap( ) method allows avoiding nested Stream<Stream<Integer>> structure:
The flatMap() operation has the effect of applying a one-to-many transformation to the elements of the stream, and then flattening the resulting elements into a new stream. The flatMap( ) general form is :
In the flatMap() method, R specifies the type of elements of the new stream, T is the type of elements of the invoking stream; and fnctn is an instance of Function, which does the mapping. The flatMap( ) function must be stateless and is an intermediate operation. Function is a functional interface declared in java.util.function, Function<T, R>, T is the element type and R is the result of the mapping. Function declares one abstract method called apply(), R apply(T t), t is a reference to the object being mapped. The mapped result is returned.
FlatMap vs Map
The map() takes a Stream and transform it to another Stream. It applies a function on each element of Stream and store return value into new Stream. It does not flatten the stream. But flatMap() is the combination of a map and a flat operation i.e, it applies a function to elements as well as flatten them. The map() is used for transformation only, but flatMap() is used for both transformation and flattening.
Program
Another Example
Program Source
import java.util.ArrayList; import java.util.stream.Stream; public class Javaapp { static Stream<Integer> stringToInStream(String str) { ArrayList<Integer> arl = new ArrayList<>(); for (int i = 0; i < str.length(); i++) { if (Character.isDigit(str.charAt(i))) { arl.add(Character.getNumericValue(str.charAt(i))); } } return arl.stream(); } public static void main(String[] args) { ArrayList<String> arystr = new ArrayList<>(); arystr.add("A9B8C7Z"); arystr.add("J4H3G2X"); arystr.add("K1B5X6V"); Stream<Stream<Integer>> strin = arystr.stream().map((e) -> stringToInStream(e)); strin.forEach((e) -> e.forEach((x) -> System.out.print(x + ","))); System.out.println(); Stream<Integer> stri = arystr.stream().flatMap((e) -> stringToInStream(e)); stri.forEach((e) -> System.out.print(e + ",")); } }
Program Source
import java.util.ArrayList; import java.util.Arrays; public class Javaapp { public static void main(String[] args) { ArrayList<ArrayList<Integer>> aryli = new ArrayList<>(); aryli.add(new ArrayList(Arrays.asList(10, 20, 30))); aryli.add(new ArrayList(Arrays.asList(40, 50, 60))); aryli.add(new ArrayList(Arrays.asList(70, 80, 90))); aryli.stream().flatMap((e)->e.stream()).forEach((e)->System.out.print(e+",")); } }