parallelStream vs stream.parallel

There is no difference between Collections.parallelStream() and Collections.stream().parallel(). They will both divide the stream to the extent that the underlying spliterator will allow, and they will both run using the default ForkJoinPool (unless already running inside another one).


Even if they act the same at the moment, there is a difference - at least in their documentation, as you correctly pointed out; that might be exploited in the future as far as I can tell.

At the moment the parallelStream method is defined in the Collection interface as:

default Stream<E> parallelStream() {
    return StreamSupport.stream(spliterator(), true);
}

Being a default method it could be overridden in implementations (and that's what Collections inner classes actually do).

That hints that even if the default method returns a parallel Stream, there could be Collections that override this method to return a non-parallel Stream. That is the reason the documentation is probably the way it is.

At the same time even if parallelStream returns a sequential stream - it is still a Stream, and then you could easily call parallel on it:

  Collections.some()
       .parallelStream() // actually sequential
       .parallel() // force it to be parallel

At least for me, this looks weird.

It seems that the documentation should somehow state that after calling parallelStream there should be no reason to call parallel again to force that - since it might be useless or even bad for the processing.

EDIT

For anyone reading this - please read the comments by Holger also; it covers cases beyond what I said in this answer.


class Employee {
    String name;
    int salary;

    public int getSalary() {
        return salary;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }

    public Employee(String name, int salary) {
        this.name = name;
        this.salary = salary;
    }
}
class ParallelStream {

    public static void main(String[] args) {

        long t1, t2;
        List<Employee> eList = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            eList.add(new Employee("A", 20000));
            eList.add(new Employee("B", 3000));
            eList.add(new Employee("C", 15002));
            eList.add(new Employee("D", 7856));
            eList.add(new Employee("E", 200));
            eList.add(new Employee("F", 50000));
        }

        /***** Here We Are Creating A 'Sequential Stream' & Displaying The Result *****/
        t1 = System.currentTimeMillis();
        System.out.println("Sequential Stream Count?= " + eList.stream().filter(e -> e.getSalary() > 15000).count());

        t2 = System.currentTimeMillis();
        System.out.println("Sequential Stream Time Taken?= " + (t2 - t1) + "\n");

        /***** Here We Are Creating A 'Parallel Stream' & Displaying The Result *****/
        t1 = System.currentTimeMillis();
        System.out.println("Parallel Stream Count?= " + eList.parallelStream().filter(e -> e.getSalary() > 15000).count());

        t2 = System.currentTimeMillis();
        System.out.println("Parallel Stream Time Taken?= " + (t2 - t1));

        /***** Here We Are Creating A 'Parallel Stream with Collection.stream.parallel' & Displaying The Result *****/
        t1 = System.currentTimeMillis();
        System.out.println("stream().parallel() Count?= " + eList.stream().parallel().filter(e -> e.getSalary() > 15000).count());

        t2 = System.currentTimeMillis();
        System.out.println("stream().parallel() Time Taken?= " + (t2 - t1));



    }

}

I had tried with all three ways .stream(),.parallelStream() and .stream().parallel(). with same number of records and able to identify timing taken by all three approach.

Here i had mentioned O/P of same.

Sequential Stream Count?= 300
Sequential Stream Time Taken?= 18
Parallel Stream Count?= 300
Parallel Stream Time Taken?= 6
stream().parallel() Count?= 300
stream().parallel() Time Taken?= 1

I am not sure,but as mentioned in O/P time taken by stream().parallel() is 1/6th of parallelStream().

Still any experts suggestions are mostly welcome.