Transforming Data with Java 8 Streams API: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
Line 45: Line 45:
{{External|https://docs.oracle.com/javase/10/docs/api/java/util/stream/Stream.html#flatMap(java.util.function.Function)}}
{{External|https://docs.oracle.com/javase/10/docs/api/java/util/stream/Stream.html#flatMap(java.util.function.Function)}}


There are situations when it is convenient to use a mapping function that produces a stream - in breaks down the elements of the original stream into ''sub-streams''. If we used the <tt>map()</tt> function directly, the result would be a Stream<Stream<T>> which in most cases has no practical uses. It would be a lot more useful to produce a Stream containing the merged content of the sub-streams. This functionality is provided by the <tt>flatMap()</tt> function. According to the documentation, <tt>flatMap()</tt> 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. Each mapped stream is closed after its contents have been placed into this stream. If a mapped stream is null an empty stream is used, instead.
There are situations when it is convenient to use a mapping function that produces a stream - in breaks down the elements of the original stream into ''sub-streams''. If we used the <tt>map()</tt> function directly, the result would be a <tt>Stream<Stream<T>></tt> which in most cases has no practical uses. It would be a lot more useful to produce a Stream containing the merged content of the sub-streams. This functionality is provided by the <tt>flatMap()</tt> function. According to the documentation, <tt>flatMap()</tt> 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. Each mapped stream is closed after its contents have been placed into this stream. If a mapped stream is null an empty stream is used, instead.


<syntaxhighlight lang='java'>
<syntaxhighlight lang='java'>
<R> Stream<R> flatMap​(Function<? super T,? extends Stream<? extends R>> mapper)
public interface Stream<T> {
 
    ...
 
    <R> Stream<R> flatMap​(Function<? super T, ? extends Stream<? extends R>> mapper);
 
    ...
 
}
</syntaxhighlight>
</syntaxhighlight>


Example:
The above call performs [[Java_Autoboxing#Autoboxing_and_Streams_API|autoboxing]] when the result of the lambda expression is a stream of primitive type. In these cases, it is advisable to use a specialized mapping function, to avoid unnecessary [[Java_Autoboxing#Autoboxing_and_Streams_API|autoboxing]]:
 
<syntaxhighlight lang='java'>
<syntaxhighlight lang='java'>
List<String> uniqueChars = words.
public interface Stream<T> {
     stream().
 
     map(word -> word.split("")).
    ...
     flatMap(Arrays::stream).
 
     distinct().
     IntStream flatMapToInt​(Function<? super T,? extends IntStream> mapper);
    collect(toList());
     LongStream flatMapToLong​(Function<? super T,? extends LongStream> mapper);
     DoubleStream flatMapToDouble​(Function<? super T,? extends DoubleStream> mapper);
 
     ...
 
}
</syntaxhighlight>
</syntaxhighlight>

Revision as of 18:35, 28 March 2018

Internal

Overview

The Stream API offers the possibility to intercept a stream and converts its elements into elements of another type, offered also as a stream. This operations is conventionally named mapping. The world mapping is used because it has a meaning similar to transforming, but with the nuance of "creating a new version" rather than "modifying".

Mapping Data

https://docs.oracle.com/javase/10/docs/api/java/util/stream/Stream.html#flat(java.util.function.Function)

The Stream API exposes the map() method, which converts the stream's elements into elements of another type, offered also as a stream. The conversion if performed by a Function<T, R> presented as the argument of the map() method.

public interface Stream<T> {

    ...

    <R> Stream<R> map(Function<? super T, ? extends R> mappingFunction);

    ...

}

The above call performs autoboxing when the result of the lambda expression is a primitive type. In these cases, it is advisable to use a specialized mapping function, to avoid unnecessary autoboxing:

public interface Stream<T> {

    ...

    IntStream mapToInt(ToIntFunction<? super T> mapper);
    LongStream mapToLong(ToLongFunction<? super T> mapper);
    DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper);
   
    ...

}

Flat-Mapping Data

https://docs.oracle.com/javase/10/docs/api/java/util/stream/Stream.html#flatMap(java.util.function.Function)

There are situations when it is convenient to use a mapping function that produces a stream - in breaks down the elements of the original stream into sub-streams. If we used the map() function directly, the result would be a Stream<Stream<T>> which in most cases has no practical uses. It would be a lot more useful to produce a Stream containing the merged content of the sub-streams. This functionality is provided by the flatMap() function. According to the documentation, flatMap() 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. Each mapped stream is closed after its contents have been placed into this stream. If a mapped stream is null an empty stream is used, instead.

public interface Stream<T> {

    ...

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

    ...

}

The above call performs autoboxing when the result of the lambda expression is a stream of primitive type. In these cases, it is advisable to use a specialized mapping function, to avoid unnecessary autoboxing:

public interface Stream<T> {

    ...

    IntStream flatMapToInt(Function<? super T,? extends IntStream> mapper);
    LongStream flatMapToLong(Function<? super T,? extends LongStream> mapper);
    DoubleStream flatMapToDouble(Function<? super T,? extends DoubleStream> mapper);
   
    ...

}