返回
Java迭代器 Spliterator: 揭秘处理并行数据的方法 (二)
Android
2024-01-13 06:55:12
从Spliterator说起
Spiltor,在英文中译为“分裂者”,可细分为“split”和“iterator”。从其名称中我们可以窥探一二,Spiltor在功能设计上主要有两点:
- 将数据源划分为多个子集合
- 创建迭代器对象,让子集合上的元素可以按顺序获取
Spiltor的引入主要解决的问题是将各种各样的数据源(譬如集合、数组等)统一抽象为标准的数据源接口,为这些数据源提供一系列共同的功能,使我们可以方便地获取其中的数据 ,方便我们进行后续的处理。
创建Spliterator
Spiltor的创建有两种方式:
- 通过
Iterable
的spliterator
方法获取 - 手动实现
Spliterator
接口
下面我们通过代码示例了解如何实现上述两种方式:
// 通过Iterable的spliterator方法获取Spliterator
List<Integer> list = new ArrayList<>();
Spliterator<Integer> spliterator1 = list.spliterator();
// 手动实现Spliterator接口
Spliterator<Integer> spliterator2 = new Spliterator<Integer>() {
// 返回Spliterator实例的估计大小
@Override
public long estimateSize() {
return 0;
}
// 将Spliterator实例划分为两个或多个Spliterator实例,以支持并行处理
@Override
public Spliterator<Integer> trySplit() {
return null;
}
// 返回Spliterator实例的下一个元素,如果没有更多元素,则返回null
@Override
public Integer tryAdvance(Consumer<? super Integer> action) {
return null;
}
// 返回Spliterator实例的特征标志,它可以是一个组合标志,其中包含 Spliterator.ORDERED、Spliterator.DISTINCT、Spliterator.SORTED 和 Spliterator.SIZED
@Override
public int characteristics() {
return 0;
}
};
Spiltor的特征
Spliterator
接口提供了一个characteristics()
方法,该方法返回一个整数,代表该Spliterator
具有的特征。这些特征可以通过按位运算符(|
)组合起来,以表示Spliterator
的多个特征。
Spliterator提供了7个特征,它们分别是:
NONE - 0
ORDERED - 1<<0
DISTINCT - 1<<1
SORTED - 1<<2
SIZED - 1<<3
NONNULL - 1<<4
IMMUTABLE - 1<<5
CONCURRENT - 1<<6
这些特征可以组合起来表示Spliterator的多个特征,例如:
Spliterator<Integer> spliterator = Arrays.asList(1, 2, 3, 4, 5).spliterator();
int characteristics = spliterator.characteristics();
if ((characteristics & Spliterator.ORDERED) != 0) {
System.out.println("Spliterator is ordered.");
}
if ((characteristics & Spliterator.DISTINCT) != 0) {
System.out.println("Spliterator is distinct.");
}
if ((characteristics & Spliterator.SORTED) != 0) {
System.out.println("Spliterator is sorted.");
}
if ((characteristics & Spliterator.SIZED) != 0) {
System.out.println("Spliterator is sized.");
}
输出:
Spliterator is ordered.
Spliterator is distinct.
Spliterator is sorted.
Spliterator is sized.
Spiltor的遍历
Spliterator提供了两种遍历方式:
- forEachRemaining
- tryAdvance
forEachRemaining
方法接受一个Consumer
函数作为参数,该函数对Spliterator的剩余元素进行操作,直到Spliterator中没有更多元素为止。该方法是最终操作,这意味着它会消耗Spliterator中的所有元素。
Spliterator<Integer> spliterator = Arrays.asList(1, 2, 3, 4, 5).spliterator();
spliterator.forEachRemaining(System.out::println);
输出:
1
2
3
4
5
tryAdvance
方法接受一个Consumer
函数作为参数,该函数对Spliterator中的下一个元素进行操作,如果没有更多元素,则返回false。该方法是非最终操作,这意味着它不会消耗Spliterator中的所有元素。
Spliterator<Integer> spliterator = Arrays.asList(1, 2, 3, 4, 5).spliterator();
while (spliterator.tryAdvance(System.out::println)) {
// do something
}
输出:
1
2
3
4
5