从集合中获取并行流

时间:2014-03-22 11:15:21

标签: java java-8 java-stream

使用Java 8是否正确执行以下代码当然Collection获取并行流?

是否正确?
private <E> void process(final Collection<E> collection) {
    Stream<E> stream = collection.parallelStream().parallel();
    //processing
}

来自Collection API:

  

默认Stream parallelStream()

     

以此集合作为源返回可能并行的Stream。此方法允许返回顺序流。

来自BaseStream API:

  

S parallel()

     

返回并行的等效流。可能会返回自己,因为流已经并行,或者因为基础流状态被修改为并行。

我需要调用一个可以将流并行化两次的函数,这不是很尴尬吗?

1 个答案:

答案 0 :(得分:3)

基本上Collection.parallelStream()的默认实现确实会创建并行流。实现如下:

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

但这是一种默认方法,对于某些实现类来说,提供不同的实现来创建顺序流也是完全有效的。例如,假设我创建了一个SequentialArrayList

class MySequentialArrayList extends ArrayList<String> {
    @Override
    public Stream<String> parallelStream() {
        return StreamSupport.stream(spliterator(), false);
    }
}

对于该类的对象,以下代码将按预期打印false

ArrayList<String> arrayList = new MySequentialArrayList();
System.out.println(arrayList.parallelStream().isParallel());

在这种情况下,调用BaseStream#parallel()方法可确保返回的流始终是并行的。通过将parallel字段设置为true,它可以是并行的,也可以是平行的:

public final S parallel() {
    sourceStage.parallel = true;
    return (S) this;
}

这是AbstractPipeline#parallel()方法的实现。

因此,同一对象的以下代码将打印true

System.out.println(arrayList.parallelStream().parallel().isParallel());

但是如果流已经是并行的,那么它是一个额外的方法调用,但这将确保您始终获得并行流。我还没有深入研究流的并行化,所以我不能评论什么样的集合或者parallelStream()会给你一个连续的流。