关于Characteristics.UNORDERED在Java 8中的行动书中的混淆

时间:2018-05-31 13:30:39

标签: java java-8 java-stream

java 8的作者在行动中写了这个类:

class ToListCollector<T> implements Collector<T, List<T>, List<T>> {

    @Override
    public Supplier<List<T>> supplier() {
        return ArrayList::new;
    }

    @Override
    public BiConsumer<List<T>, T> accumulator() {
        return List::add;
    }

    @Override
    public BinaryOperator<List<T>> combiner() {
        return (l1, l2) -> {
            l1.addAll(l2);
            return l1;
        };
    }

    @Override
    public Function<List<T>, List<T>> finisher() {
        return Function.identity();
    }

    @Override
    public Set<Characteristics> characteristics() {
        return Collections.unmodifiableSet(EnumSet.of(Characteristics.IDENTITY_FINISH, Characteristics.CONCURRENT));
    }
}

然后他谈到了特征枚举的不同价值。然后他解释了为什么他写的这个收藏家是IDENTITY_FINISH和CONCURRENT而不是UNORDERED,说:

  

到目前为止开发的ToListCollector是IDENTITY_FINISH,因为List习惯了   累积流中的元素已经是预期的最终结果,不需要任何   进一步转换,但它不是UNORDERED,因为如果你将它应用于有序流   您希望在结果列表中保留此顺序。最后,它是和谐的,但是   按照我们刚才所说的,只有在其基础数据的情况下才会并行处理流   来源无序。

为什么只有在基础源无序时才会并行处理流?我认为它仍然会并行处理,但是combiner()必须保留顺序。这本书是错误吗?

我认为Brian Goetz在最后一个parahraph中明确地讨论了this post中有序流的并行处理。

书中的页面是192 - 193。

1 个答案:

答案 0 :(得分:7)

这是完全错误的。即使在此处添加CONCURRENT特性也是错误的,因为在Supplier中需要线程安全的数据结构。