6.3.  Use the merge() and flatMap() methods

  • blah


<R> Stream<R> flatMap(Function<? super T,? extends Stream<? extends R>> mapper)


The Stream.flatMap(...) method returns a stream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element. The function produces a stream for each input element and the output streams are flattened. Performs one-to-many mapping.

The flatMap operation works as follows:

Let's look at a simple example. We have got a Stream of lists of names, and we want all the names from these in sequences. We can solve this problem using an approach like the one in example below:

List<String> names1 = Arrays.asList("Dzmitry", "John");
List<String> names2 = Arrays.asList("David", "Laura");
Stream<List<String>> s = Stream.of(names1, names2);
s.flatMap(names -> names.stream()).forEach(System.out::println);




We replace the List<String> with a Stream<String> using the stream() method, and flatMap does the rest. The flatMap's associated functional interface is the same as map's — the Function — but its return type is restricted to streams and not any value.

The flatMap(...) transforms each element of a stream into another form (just like map(...)), and generates sub-streams of the newly formed elements. Finally, it flattens all of the sub-streams into a single stream of elements. As the flatMap(...) is a map type of function, it also takes a function and applies (maps) that function to each of the element in the stream.

The difference between map(...) and flatMap(...) is:


The java.util.Map interface has been extended with the merge function in Java 8:

default V  merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction)


The Map.merge(...) method does the following: if the specified key is not already associated with a value or is associated with null, associates it with the given value. Otherwise, replaces the value with the results of the given remapping function, or removes if the result is null.

The default implementation of merge is equivalent to performing the following steps for this map, then returning the current value or null if absent:

V oldValue = map.get(key);
V newValue = (oldValue == null) ? value : remappingFunction.apply(oldValue, value);
if (newValue == null)
    map.put(key, newValue);

The default implementation makes no guarantees about synchronization or atomicity properties of this method.

Professional hosting         Free 'Oracle Certified Expert Web Services Developer 6' Guide     Exam 1Z0-810: Upgrade to Java SE 8 Programmer Quiz