When I run the following code:
Stream.of("a", "b", "c")
.flatMap(s -> Stream.of(s, s+s))
.map(s -> {System.out.printf("complex operation on %s\n", s); return s;})
.findFirst()
.ifPresent(s -> System.out.printf("outcome %s\n", s));
...the map operation runs for the first two elements in the stream, instead of just the first one:
complex operation on a
complex operation on aa
outcome a
However, if I explicitly collect after the flatMap:
Stream.of("a", "b", "c")
.flatMap(s -> Stream.of(s, s + s))
.collect(Collectors.toList())
.stream()
.map(s -> {System.out.printf("complex operation on %s\n", s); return s;})
.findFirst()
.ifPresent(s -> System.out.printf("outcome %s\n", s));
...then the map operation runs on only the first element, as I'd expect.
Why is there a difference, and how can I can I get the map to only process the first item without collecting the whole incoming stream?
Please note that this is not my actual code. In practice I need to filter after the map and before the findFirst, so I can't do something like call findFirst before map.
I also tried:
.sequential()after theflatMap(no effect).sorted()after theflatMap(works, but reads the whole stream, and in my real application it doesn't actually make sense to sort)