Reputation: 17890
I thought that all stream pipelines written using flatMap()
can be converted to use mapMulti
. Looks like I was wrong when the flatMap()
or mapMulti()
returns/operates on an infinite stream.
Note: this is for educational purpose only
When we map an element to an infinite stream inside a flatMap()
followed by a limit()
, then the stream pipeline is lazy and evaluates as per the required number of elements.
list.stream()
.flatMap(element -> Stream.generate(() -> 1))
.limit(3)
.forEach(System.out::println);
Output:
1
1
1
But when doing the same in a mapMulti()
, the pipeline is still lazy i.e., it doesn't consume the infinite stream. But when running this in IDE (Intellij), it hangs and doesn't terminate (I guess waiting for other elements consumption) and doesn't come out of the stream pipeline execution.
With a mapMulti()
,
list.stream()
.mapMulti((element, consumer) -> {
Stream.generate(() -> 1)
.forEach(consumer);
})
.limit(3)
.forEach(System.out::println);
System.out.println("Done"); //Never gets here
Output:
1
1
1
But the last print (Done
) doesn't get executed.
Is this the expected behaviour?
I couldn't find any warning or points on infinite stream and mapMulti()
in Javadoc.
Upvotes: 2
Views: 1370
Reputation: 28988
The advantage of mapMulti()
is that it consumes new elements which became a part of the stream, replacing the initial element (opposed to flatMap()
which internally generates a new stream for each element). If you're generating a fully-fledged stream with a terminal operation inside the mapMulti()
it should be executed. And you've created an infinite stream which can't terminate (as @Lino has pointed out in the comment).
On the contrary, flatMap()
expects a function producing a stream, i.e. function only returns it not processes.
Here's a quote from the API note that emphasizes the difference between the two operations:
API Note:
This method is similar to
flatMap
in that it applies a one-to-many transformation to the elements of the stream and flattens the result elements into a new stream. This method is preferable toflatMap
in the following circumstances:
- When replacing each stream element with a small (possibly zero) number of elements. Using this method avoids the overhead of creating a new Stream instance for every group of result elements, as required by
flatMap
.
Upvotes: 3