java 接口Spliterator源码分析

目录

Spliterator简介

tryAdvance

forEachRemaining

trySplit

estimateSize

getExactSizeIfKnown

characteristics,hasCharacteristics,getComparator

各种特征

OfPrimitive

OfInt


Spliterator简介

public interface Spliterator<T> {
  

Spliterator是一个可分割迭代器(splitable iterator),可以和iterator顺序遍历迭代器一起看。jdk1.8发布后,对于并行处理的能力大大增强,Spliterator就是为了并行遍历元素而设计的一个迭代器,jdk1.8中的集合框架中的数据结构都默认实现了spliterator

 

下面是我对jdk注释的对应翻译,看完基本上就大概懂了一大半了

可以看到注释中,还有jdk自带的一个实现spliterator接口的案例,和使用它的样例,值得参考

/**
 * 
 * <p>一个类,为了遍历并且分割一个来源的元素。这些元素可以被一个spliterator覆盖,举个例子,
 * 一个数组,一个collection,一个io的channel或者一个工厂功能
 *
 * <p>一个spliterator可能独自地遍历元素(通过tryAdvance)或者成批地,连续地遍历(通过forEachRemaining)
 * 
 * <p>一个spliterator可能隔开它的一些元素(使用trySplit)作为另一个spliterator,用作可能并发的操作。
 * 使用一个不能分割或者以高度不平衡或者低效率的方式分割的spliterator的行为,很可能不会因为并发收益。
 * 遍历和分割耗尽元素,每个spliterator队一个单独的块计算有效
 * 
 * <p>一个spliterator也能报告一个它的结构,来源,元素的特征集(通过characteristics()),包括
 * ordered,distinct,sorted,sized,nonnull,immutable,concurrent,subsized。
 * 这些可能会被spliterator的使用者使用,来控制,特殊化或者简单化计算。
 * 例如,一个collection的spliterator会报告sized,set报告distinct,sorted set报告distinct和sorted
 * 特征集会被以一个简单的bitset的形式被报告。
 * 
 * <p>一些特征集额外地限制方法的行为。例如,如果是ordered,遍历方法必须符合他们表明的有序。
 * 续保的特征集可能会在未来被定义,所以实现类不应该对未被标明的值指派意义。
 * 
 * <p>一个没有报告immutable或者concurrent的spliterator应该有一个文档化的策略:
 * 当spliterator与元素来源绑定,并且对元素来源的结构的干扰会在绑定后被检测到。
 * 一个迟绑定的spliterator在第一次遍历,第一次分割或者第一次对预计大小查询时与元素来源绑定,而不是在spliterator被创建时绑定。
 * 一个不是迟绑定的spliterator在创建或者任何方法的第一次调用时绑定。
 * 在绑定之前对来源的修改会在spliterator遍历时显示出来。
 * 在绑定一个spliterator后,应该基于一个最大努力的假设,如果结构的干扰被检测出,则抛出一个ConcurrentModificationException的错误。
 * 如此做的spliterator被称为fail-fast,快速失败。
 * spliterator的成块遍历的方法(forEachRemaining)可能优化遍历并且在所有元素被遍历完后检查对结构的干扰,而不是遍历每个元素时都检查,然后立即失败。
 * 
 * <p>spliterators 能提供一个预计残留的元素的数目,通过estimatesize方法。
 * 理想上,当体现在特征为sized时,这个值准确地对应元素的多少,那会导致一个完美的遍历。
 * 然而,甚至当没有准确地知道时,一个预估大小的值可能对源头的操作有用,例如帮助决定是继续分割还是连续地遍历剩余的元素哪个更有利。
 * 
 * <p>尽管spliterators明显在并发算法中很实用,但是它们不有被预计为是线程安全的。
 * 相反,使用spliterators的并法算法的实现,应该确保spliterator应该同一时间只被一个线程使用。
 * 这通常很容易达到,通过串行线程封闭,这通常是一个通过递归的分解来工作的典型并发算法的自然结果。
 * 一个调用trysplit的线程可能移交返回的spliterator给另一个线程,它可能轮流遍历这个spliterator或者分割它。
 * 如果两个或以上的线程并发地操作同一个spliterator时,分割或者遍历的行为是不确定的。
 * 如果最初的线程将一个spliterator转交给另一个线程来处理,那么最好在任何元素被tryAdvance消费前传递它,
 * 因为某些保证(例如sized的spliterator的estimatesize方法的准确性)仅仅在遍历开始前有效。
 * 
 * <p>spliterator对基本类(int,long,double)的实现被提供了。
 * 这些子类的默认实现的tryAdvance和forEachRemaining包装了基本值对他们对于的包装类。
 * 这样的包装可能破坏任何通过使用基本类型获得优势的行为。
 * 为了避免包装,对于的基于基本类型的方法应该被使用。
 * 例如OfInt的tryAdvance(IntConsumer)和forEachRemaining(IntConsumer)方法应该被使用,
 * 优先于tryAdvance(Consumer)和forEachRemaining(Consumer)
 * 使用基于包装类的方法(tryAdvance和forEachRemaining)遍历基本值,不影响值转换为包装值的顺序。
 * 
 * <p>spliterators,像iterator,是为了遍历一个来源的元素。
 * spliterator这个api被设计用来提供有效的并发遍历,取代了连续遍历,通过支持分解和单元素迭代。
 * 此外,通过一个spliterator访问元素的协议,被设计用来让每个元素的开销比iterator小,
 * 并且避免有hasNext和next这样的继承的方法
 *
 * <p>对于可更改的来源,随意的和非确定性的行为可能发生,如果来源的结构在spliterator与来源绑定和遍历结束之间,被元素添加,替换,删除等行为干扰。
 * 举个例子,当使用stream框架是,这些行为会产生随意的随意的和非确定性的结果。
 *
 * <p>Structural interference of a source can be managed in the following ways
 * (in approximate order of decreasing desirability):
 * 
 * <p>对来源的结构的干扰能以下面的方法管理(通过降低吸引力的近似顺序)
 * <p>1 来源的结构不能被干扰。比如CopyOnWriteArrayList是个不可更改的来源。
 * 从这种来源产生的spliterator会报告特征immutable
 * <p>2 来源管理并发的修改,比如ConcurrentHashMap是个并发的来源,这种会报告concurrent
 * <p>3 可变的来源提供一个迟绑定的和fail-fast的spliterator。迟绑定缩短了干扰影响计算的窗口期。
 * fail-fast机制以基于最大努力的假设,探测出在遍历开始后的干扰并抛出ConcurrentModificationException
 * 比如,arraylist和许多其他的jdk中的肺病发的类,提供一个迟绑定,fail-fast的spliterator
 * <p>4 可变的来源提供一个非迟绑定,fail-fast的spliterator。
 * 来源增长了抛出ConcurrentModificationException的可能性,因为增加了干扰影响计算的窗口期。
 * <p>5 可变的来源提供一个迟绑定,非fail-fast的spliterator。
 * 这个来源受到遍历开始后进行随意的,非确定性操作的影响,因为干扰没有被检
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值