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。
答案 0 :(得分:7)
这是完全错误的。即使在此处添加CONCURRENT
特性也是错误的,因为在Supplier
中需要线程安全的数据结构。