首页 > 解决方案 > 为什么 flatMap 后采集会改变 Stream 处理顺序?

问题描述

当我运行以下代码时:

    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

但是,如果我明确地collectflatMap

    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在 the 之后map和之前findFirst,所以我不能做类似 call findFirstbefore的事情map

我也试过:

标签: javajava-8java-stream

解决方案


看起来根本原因的答案也在这里:为什么在 flatMap() 之后的 filter() 在 Java 流中“不完全”是惰性的?

显然,这是一个将在 Java 10 中修复的已知错误。请参阅JDK-8075939


推荐阅读