Separators that cannot even give an approximate size (which is the default implementation for Iterable ) are loosely separated by a parallel pipeline. You can fix this problem if you track the size of the List . In your case, itβs not very difficult to track the exact size:
public abstract class List<A> implements Iterable<A> { ... public abstract long size(); @Override public Spliterator<A> spliterator() { return Spliterators.spliterator(iterator(), size(), Spliterator.ORDERED); } } class Nil extends List { ... public long size() { return 0; } } class Cons<A> extends List<A> { ... private final long size; Cons(A head, List<A> tail) { this.head = head; this.tail = tail; this.size = tail.size()+1; } ... @Override public long size() { return size; } }
After that, parallelization will work better. Please note that this is still a poor parallelization of people, because you cannot quickly jump to the middle of the list, but in many cases this will provide reasonable acceleration.
Also note that it is better to explicitly specify the Spliterator.ORDERED attribute. Otherwise, the order may be ignored in parallel streaming operations, even if it is explicitly requested (for example, with the forEachOrdered() operation).
source share