5

使用 Java 8 是否需要执行以下代码才能确定从 a 获取并行流Collection

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

CollectionAPI:

默认流并行流()

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

BaseStreamAPI:

S 并行()

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

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

4

1 回答 1

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());

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

于 2014-03-22T11:43:23.130 回答