.map返回的Java-8 Stream将是并行还是顺序?

时间:2016-01-10 21:24:14

标签: java java-8 java-stream

Streammap方法返回的

mapToObj始终是顺序的,还是取决于调用流的状态是否为并行?

IntStream的文档没有明确回答这个问题,或者我无法理解它:

我想知道来自以下示例的流是否会并行到最后,或者它会在某个时刻发生变化。

IntStream.range(1, array_of_X.size())
        .parallel()
        .mapToObj (index -> array_of_X.get(index)) // mapping#1
        .filter (filter_X)
        .map (X_to_Y) //mapping#2
        .filter (filter_Y)
        .mapToInt (obj_Y_to_int) //mapping#3
        .collect(value -> Collectors.summingInt(value));

1 个答案:

答案 0 :(得分:6)

不,它永远不会改变(除非你自己明确地改变它)。

您所写的内容对应于Stream管道,而单个管道具有单一方向:并行或顺序。所以没有"平行到最后"因为整个管道将并行执行或者将按顺序执行。

引用Stream package Javadoc:

  

此示例的串行和并行版本之间的唯一区别是使用" parallelStream()"创建初始流。而不是" stream()"。当启动终端操作时,根据调用它的流的方向,顺序地或并行地执行流管道。可以使用isParallel()方法确定流是以串行还是并行方式执行,并且可以使用BaseStream.sequential()BaseStream.parallel()操作修改流的方向。当启动终端操作时,根据调用它的流的模式,顺序地或并行地执行流管道。

这意味着Stream管道更改其方向的唯一方法是调用sequential()parallel()方法之一。由于这是Stream API的全局,因此不是为每个操作编写,而是在Javadoc包中编写。

使用您的问题中的代码,Stream管道将并行执行,因为您通过调用parallel()明确地更改了Stream方向。

重要的是要注意,Stream的结果将是对parallel()sequential()最后调用。请考虑以下三个示例:

public static void main(String[] args) {
    System.out.println(IntStream.range(0, 10).isParallel());
    System.out.println(IntStream.range(0, 10).parallel().isParallel());
    System.out.println(IntStream.range(0, 10).parallel().map(i -> 2*i).sequential().isParallel());
}
  1. 第一个将打印false,因为IntStream.range会返回连续的流
  2. 自我们调用true
  3. 后,第二个将打印parallel()
  4. 第三个将打印false,因为即使我们在管道中调用parallel(),我们之后也会调用sequential(),因此它会将Stream管道的总方向重置为serial。 / LI>

    请注意,仍然引用:

      

    JDK中的流实现创建串行流,除非明确请求并行性。

    因此,除非您明确要求并行流,否则您要检索的每个Stream都将是顺序的。