这个问题在这里已有答案:
当我运行以下代码时:
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));
... map
操作为流中的前两个元素运行,而不仅仅是第一个元素:
complex operation on a
complex operation on aa
outcome a
但是,如果我在collect
后明确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));
...然后map
操作仅在第一个元素上运行,正如我所期望的那样。
为什么会有差异,我怎样才能让map
只处理第一个项目而不收集整个传入流?
请注意,这不是我的实际代码。在实践中,我需要在filter
之后和map
之前的findFirst
,所以我不能做像findFirst
之前调用map
。
我也尝试过:
.sequential()
之后的flatMap
(没有效果).sorted()
之后的flatMap
(工作,但是读取整个流,并且在我的实际应用中它实际上没有意义排序)看起来根本原因的答案也在这里:Why filter() after flatMap() is "not completely" lazy in Java streams?
显然,这是一个已知的错误,将在Java 10中修复。请参阅JDK-8075939。