9

Stream returned by map or mapToObj methods is always sequential or does it depend on whether the state of the calling stream was parallel or not?

The documentation of IntStream does not answer this explicitly or I cannot understand it properly:

I am wondering if my stream from the following example will be parallel up to the end or it will change at some point.

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));
Tunaki
  • 132,869
  • 46
  • 340
  • 423
Dominik
  • 331
  • 1
  • 4
  • 12
  • 1
    Possible duplicate of [Java 8 Stream api: why the distinction between sequential and parallel execution mode?](http://stackoverflow.com/questions/22950642/java-8-stream-api-why-the-distinction-between-sequential-and-parallel-execution) – Andy Turner Jan 10 '16 at 21:25

1 Answers1

9

No, it will never change (unless you explicitely change it yourself).

What you have written corresponds to a Stream pipeline and a single pipeline has a single orientation: parallel or sequential. So there is no "parallel up to the end" because either the whole pipeline will be executed in parallel or it will be executed sequentially.

Quoting the Stream package Javadoc:

The only difference between the serial and parallel versions of this example is the creation of the initial stream, using "parallelStream()" instead of "stream()". When the terminal operation is initiated, the stream pipeline is executed sequentially or in parallel depending on the orientation of the stream on which it is invoked. Whether a stream will execute in serial or parallel can be determined with the isParallel() method, and the orientation of a stream can be modified with the BaseStream.sequential() and BaseStream.parallel() operations. When the terminal operation is initiated, the stream pipeline is executed sequentially or in parallel depending on the mode of the stream on which it is invoked.

This means that the only way for a Stream pipeline to change its orientation is by calling one of sequential() or parallel() method. Since this is global to the Stream API, this is not written for every operation but in the package Javadoc instead.

With the code in your question, the Stream pipeline will be executed in parallel because you explicitely changed the Stream orientation by invoking parallel().


It is important to note that the resulting orentiation of the Stream will be the last call made to parallel() or sequential(). Consider the three following examples:

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. The first one will print false since IntStream.range returns a sequential Stream
  2. The second one will print true since we invoked parallel()
  3. The third one will print false since, even if we call parallel() in the pipeline, we invoked sequential() afterwards so it reset the total orientation of the Stream pipeline to serial.

Note that, still quoting:

The stream implementations in the JDK create serial streams unless parallelism is explicitly requested.

so every Stream you are going to retrieve will be sequential unless you explicitely requested a parallel Stream.

Tunaki
  • 132,869
  • 46
  • 340
  • 423