为什么flatMap之后收集会更改Stream处理顺序?

时间:2018-08-29 04:00:10

标签: java java-8 java-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

但是,如果我在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之后(可以,但是会读取整个流,在我的实际应用程序中,排序实际上没有任何意义)

1 个答案:

答案 0 :(得分:0)

看起来根本原因的答案也在这里:Why filter() after flatMap() is "not completely" lazy in Java streams?

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