2

Having the following simple example of a java stream

Stream<Integer> s123 = Stream.of(1, 2, 3);
List<String> abc = Arrays.asList("a", "b", "c");
s123.flatMap(i -> abc.stream())
    .peek(System.out::println)
    .findFirst()
    .ifPresent(System.out::println);

What would you expect the peek will print? I was expecting just "a", since the findFirst should short circuit the evaluation of the stream. Unfortunately this is not what happens. The peek method prints "a", "b", "c". This seems to be the case since the stream is created by flatMap concatenating the same stream three times. The problem I am facing is, if someone provides a method, which returns a stream, e.g.

Stream<String> multipleOf(int i, String ...s)

one really needs to know the implementation of this method when using the stream. The real world example did not use peek (which I used for illustration here), but a map operation doing some heavy work. In the end it caused some serious performance problems, since a lot more elements where mapped than expected. So when it comes to performance, it seems to be safest to rely on the good old for loop - although I do like the streams very much. Any thoughts on how to deal with these problems are welcome.

dastrobu
  • 1,600
  • 1
  • 18
  • 32
  • 3
    This is a bug in the flatMap method which was fixed in Java 10 or something. Which Java version are you on? – marstran Apr 11 '19 at 15:08
  • 3
    This may be a duplicate of [Why filter() after flatMap() is “not completely” lazy in Java streams?](https://stackoverflow.com/questions/29229373/why-filter-after-flatmap-is-not-completely-lazy-in-java-streams), but TL;DR. Please check Holger's answer. I also think this was addressed in later JDK versions. Which version are you running? – ernest_k Apr 11 '19 at 15:08
  • The function passed to `flatMap` is only evaluated once. What gets printed are the three elements of a single sub-stream. And, well, I don’t see how you could rewrite the use of a stream returning method, which may or may not incorporate `flatMap`, into a “good old for loop”, as each `flatMap` step would represent a nested loop and having a variable number of nested loops is far away from being trivial… – Holger Apr 11 '19 at 15:14
  • 1
    Unfortunately still on java 1.8. So this explains the behaviour. Thanks for pointing to https://stackoverflow.com/questions/29229373/why-filter-after-flatmap-is-not-completely-lazy-in-java-streams this question seems to address the same issue. – dastrobu Apr 11 '19 at 15:39

0 Answers0