介绍:
Java中的迭代器用于遍历给定源的元素。 Java中的Spliterator是四个可用的Java迭代器之一 -Iterator ,Enumeration, ListIterator和Spliterator 。 它是java.util包中可用的接口。
Spliterator最初是在Java 8中引入的,以支持并行编程。 但是,我们可以将其用于数据项的顺序和并行处理。 要获取Java Spliterator的实例,我们将使用spliterator()方法:
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Spliterator splitr = list.spliterator();
我们可以将Java Spliterator视为:
Spliterator = Splitting + Iteration
Spliterator接口定义一些表示其特征的整数常量。 我们的实例可以具有以下八个特征中的一个或多个:
- SIZED –能够在调用estimateSize()方法时返回源中确切数量的元素
- SUBSIZED –当我们使用trySplit ()拆分实例并获得SIZED SplitIterators时
- ORDERED –在有序序列上迭代
- 分类 -遍历一个排序序列
- NONNULL –源保证不具有空值
- DISTINCT-我们的源序列中不存在重复项
- IMMUTABLE –如果我们无法在结构上修改元素源
- 并发 -元素源可以同时安全地修改
我们可以使用int Characteristics ()方法来查询我们的Spliterator实例的特征。 它为我们的Spliterator返回所有合格特征值的OR'ed值。 对于我们定义的splitr ,我们将有:
int charactersticsORed = splitr.characteristics(); //16464
我们可以使用boolean hasCharacteristics(int特征)方法来检查我们的实例是否具有给定的特征 :
boolean isSized = splitr.hasCharacteristics(Spliterator.SIZED); //true
boolean isSorted = splitr.hasCharacteristics(Spliterator.SORTED); //false
boolean isNonNull = splitr.hasCharacteristics(Spliterator.NONNULL); //false
estimateSize()方法返回要迭代的剩余元素的估计数量。 如果该值无限大,未知或计算成本太高,则返回Long.MAX_VALUE 。 对于SIZED拆分器,它返回一个值,该值与成功遍历中遇到的元素数完全对应:
long estimatedSize = splitr.estimateSize(); // 5
这只是一个方便的方法,如果它是SIZED Spliterator或返回-1 ,则返回estimateSize() :
long size = splitr.getExactSizeIfKnown(); // 5
tryAdvance()方法的签名如下所示:
default boolean tryAdvance(Consumer<? super T> action)
在Spliterator的tryAdvance()方法结合了hasNext()和next()运营商呈现在碱性迭代器 。 因此,如果存在剩余元素,它将对它执行给定的操作,并返回true;否则,返回true。 否则返回false 。 换句话说, 它对序列中的下一个元素执行操作 ,然后使迭代器前进。
while(splitr.tryAdvance((item) -> System.out.println(item)));
如果我们有ORDERED Spliterator , 则按遇到顺序对下一个元素执行操作。
forEachRemaining(Consumer <?superT> action)方法在当前线程中依次为每个剩余元素执行给定操作,直到所有元素都已处理或该操作引发异常:
splitr.forEachRemaining(item -> System.out.println(item));
当前的默认实现重复调用tryAdvance(),直到返回false为止。
如果可以进行分区,则trySplit()方法将拆分调用方的Spliterator并返回对该Spliterator覆盖元素的引用,该元素在从此方法返回时不会被此Spliterator覆盖。 否则,它返回null 。
因此,在成功拆分之后,原始的Spliterator将在序列的一部分上进行迭代,而返回的Spliterator将在序列的另一部分上进行迭代。
同样, 返回的Spliterator包含初始ORDERED Spliterator的元素的严格前缀(例如,在List上 ) :
// trySplit() method over ORDERED splitr
Spliterator<Integer> splitrNew = splitr.trySplit(); // Elements in our splitrNew = {1, 2, 3}
if(splitrNew != null) { splitrNew.forEachRemaining((n) -> System.out.println(n));
} // Elements in our splitr - {4 , 5}
splitr.forEachRemaining((n) -> System.out.println(n));
除非我们原始的Spliterator表示无限序列,否则对trySplit()的重复调用最终必须返回null 。
如果我们有一个由比较器 排序的分隔器 ,它将返回该比较器 。 否则,如果源以自然顺序排序,则返回null 。 对于未排序的源,它将抛出IllegalStateException 。
因此,对于我们的示例,我们有:
Comparator<Integer> comparator = splitr.getComparator(); //throws IllegalStateException
为什么要使用Spliterator?
Java Spliterator为我们提供了以下优点:
- 支持并行编程
- 我们可以将其用于数据项的顺序和并行处理
- tryAdvance ()方法结合了简单迭代器的 next()和hasNext()操作,因此可提供更好的性能
同样,重要的是要意识到,分离器对于Collection和Stream源都可以正常工作,但不适用于Map实现。
结论:
在本文中,我们向您介绍了Java的Spliterator接口。 我们介绍了此界面中可用的不同默认方法以及如何使用它们。
成为第一个发表评论的人。
翻译自: https://www.javacodegeeks.com/2019/04/using-spliterator-java.html