Spliterator
Spliterator 是Java 8新加入的一个接口:这个名字代表“可分迭代器”(splitable iterator)。
和Iterator 一样,Spliterator也用于遍历数据源中的元素,但他是为了并行执行而设计的。
开发中一般不用自己开发Spliterator。
Java 8 已经为集合框架中包含的所有数据结构提供了一个默认的Spliterator实现。集合实现了Spliterator接口,接口提供了一个spliterator 方法。这个接口定了若干方法。
public interface Spliterator<T> {
boolean tryAdvance(Consumer<? super T> action);
Spliterator<T> trySplit();
long estimateSize();
int characteristics();
}
T 是Spliterator遍历的元素类型。
tryAdvance(试着前进)方法的行为类似于普通的Iterator,因为它会按顺序一个一个使用Spliterator中的元素,并且如果还有其他元素要遍历就返回true。
trySplit是专为Spliterator接口设计的,因为它可以把一些元素划出去分给第二个Spliterator(由该方法返回),让它们两个并行处理。Spliterator还可通过 estimateSize(估计大小)方法估计还剩下多少元素要遍历,因为即使不那么确切,能快速算出来世一个值也有助于让拆分均匀一点。
拆分过程
将Stream 拆分成多个部分的算法是一个递归过程。
如图所示,第一步是对第一个Spliterator调用trySplit,生成第二个Spliterator。第二步对这两个Spliterator调用trySplit,这样总共就有了四个Spliterator。这个框架不断对Spliterator调用trySplit直到它返回null,表名它处理的数据结构不能再分割,如第三步所示。最后,这个递归拆分过程到第四部就终止了,这时所有的Spliterator再调用trySplit时都返回了null。
拆分过程也受Spliteraotr本身的特性影响,而特性是通过characteristics方法声明的。
Spliterator 的特性
Spliterator接口声明的最后一个抽象方法是characteristics,它将返回一个int,代表Spliterator本身特性集的编码。使用Spliterator的客户可以用这些特性来更好地控制和优化它的使用。
表 7-2 Spliterator的特性
特性 | 含义 |
---|---|
ORDERED | 元素有特定的顺序(如List),因此Spliterator在遍历和划分时也会遵循这一顺序 |
DISTINCT | 对于任意一对遍历过的元素x和y,x.eq |