Spliterator
public interface Spliterator<T>
用于遍历和划分源元素的对象。 Spliterator 覆盖的元素来源可以是,例如,数组、集合、IO 通道或生成器函数。
Spliterator 可以单独遍历元素(tryAdvance())或批量顺序遍历元素(forEachRemaining())。
Spliterator 也可以将它的一些元素(使用 trySplit())划分为另一个 Spliterator,以用于可能的并行操作。 使用无法拆分或以高度不平衡或低效的方式拆分的 Spliterator 操作不太可能从并行性中受益。 遍历和拆分排气元件; 每个 Spliterator 仅对单个批量计算有用。
Spliterator 还报告其结构、源和元素的一组特征(),来自 ORDERED、DISTINCT、SORTED、SIZED、NONNULL、IMMUTABLE、CONCURRENT 和 SUBSIZED。 Spliterator 客户端可以使用这些来控制、专门化或简化计算。 例如,Collection 的 Spliterator 会报告 SIZED,Set 的 Spliterator 会报告 DISTINCT,SortedSet 的 Spliterator 也会报告 SORTED。 特征被报告为一个简单的联合位集。 一些特征还限制了方法的行为; 例如,如果 ORDERED,遍历方法必须符合其记录的顺序。 未来可能会定义新的特性,因此实现者不应为未列出的值赋予含义。
不报告 IMMUTABLE 或 CONCURRENT 的 Spliterator 应该有一个文档化的策略,涉及: 当 spliterator 绑定到元素源时;结合后检测到的元素源的结构干扰检测。后期绑定 Spliterator 在第一次遍历、第一次拆分或第一次查询估计大小时绑定到元素的源,而不是在创建 Spliterator 时。非后期绑定的 Spliterator 在构造点或任何方法的第一次调用时绑定到元素的源。绑定之前对源所做的修改会在遍历 Spliterator 时反映出来。绑定 Spliterator 后,如果检测到结构干扰,应尽最大努力抛出 ConcurrentModificationException。执行此操作的拆分器称为快速失败。 Spliterator 的批量遍历方法 (forEachRemaining()) 可以优化遍历并在遍历所有元素后检查结构干扰,而不是检查每个元素并立即失败。
Spliterators 可以通过estimateSize() 方法估计剩余元素的数量。 理想情况下,正如 SIZED 特性所反映的那样,该值恰好对应于成功遍历中将遇到的元素数量。 然而,即使在不完全知道的情况下,估计值仍然可能对在源上执行的操作有用,例如帮助确定进一步拆分或顺序遍历剩余元素是否更可取。
尽管它们在并行算法中有明显的用途,但分离器并不期望是线程安全的。 相反,使用拆分器的并行算法的实现应确保拆分器一次仅由一个线程使用。 这通常很容易通过串行线程限制来实现,这通常是通过递归分解工作的典型并行算法的自然结果。 调用 trySplit() 的线程可以将返回的 Spliterator 移交给另一个线程,该线程又可以遍历或进一步拆分该 Spliterator。 如果两个或多个线程在同一个拆分器上同时操作,拆分和遍历的行为是不确定的。 如果原始线程将拆分器交给另一个线程进行处理,最好在 tryAdvance() 消耗任何元素之前进行该切换,因为某些保证(例如 SIZED 拆分器的估计大小()的准确性)仅有效 在遍历开始之前。
为 OfInt、OfLong 和 OfDouble 值提供了 Spliterator 的原始子类型特化。 Spliterator#tryAdvance(java.util.function.Consumer) 和 Spliterator#forEachRemaining(java.util.function.Consumer) 的子类型默认实现将原始值框到其相应包装类的实例中。 这种装箱可能会破坏使用原始专业化获得的任何性能优势。 为避免装箱,应使用相应的基于基元的方法。 例如,应该优先使用 Spliterator.OfInt#tryAdvance(java.util.function.IntConsumer) 和 Spliterator.OfInt#forEachRemaining(java.util.function.IntConsumer),而不是 Spliterator.OfInt#tryAdvance(java.util.function。 消费者)和 Spliterator.OfInt#forEachRemaining(java.util.function.Consumer)。 使用基于装箱的方法 tryAdvance() 和 forEachRemaining() 遍历原始值不会影响遇到转换为装箱值的值的顺序。
嵌套类摘要
修饰符和类型 | 接口 | 描述 |
---|---|---|
static interface | Spliterator.OfDouble | 专门用于double值的 Spliterator。 |
static interface | Spliterator.OfInt | 专门用于 int 值的 Spliterator。 |
static interface | Spliterator.OfLong | 专门用于long值的 Spliterator。 |
static interface | Spliterator.OfPrimitive<T,T_CONS,T_SPLITR extends Spliterator.OfPrimitiveT,T_CONS,T_SPLITR> | 专用于primitive值的 Spliterator。 |
字段摘要
修饰符和类型 | 字段 | 描述 |
---|---|---|
static int | CONCURRENT | 特征值表示元素源可以被多个线程安全地同时修改(允许添加、替换和/或删除)而无需外部同步。 |
static int | DISTINCT | 特征值表示,对于每对遇到的元素 x, y, !x.equals(y)。 |
static int | IMMUTABLE | 表示元素源不能进行结构修改的特征值; 也就是说,元素不能被添加、替换或删除,因此在遍历过程中不会发生这种变化。 |
static int | NONNULL | 表示源保证遇到的元素不会为空的特征值。 |
static int | ORDERED | 表示为元素定义相遇顺序的特征值。 |
static int | SIZED | 特征值表示在遍历或拆分之前从estimateSize() 返回的值表示有限大小,在没有结构源修改的情况下,表示完整遍历将遇到的元素数量的精确计数。 |
static int | SORTED | 表示遇到顺序遵循定义的排序顺序的特征值。 |
static int | SUBSIZED | 特征值表示由 trySplit() 产生的所有拆分器都将是 SIZED 和 SUBSIZED。 |
方法总结
修饰符和类型 | 方法 | 描述 |
---|---|---|
int | characteristics() | 返回此 Spliterator 及其元素的一组特征。 |
long | estimateSize() | 返回 forEachRemaining(java.util.function.Consumer) 遍历将遇到的元素数量的估计值,如果无限、未知或计算成本太高,则返回 Long#MAX_VALUE。 |
default void | forEachRemaining(Consumer<? super T> action) | 在当前线程中按顺序对每个剩余元素执行给定的操作,直到处理完所有元素或该操作引发异常。 |
default Comparator<? super T> | getComparator() | 如果此 Spliterator 的源由 Comparator 排序,则返回该 Comparator。 |
default long | getExactSizeIfKnown() | 如果此 Spliterator 为 SIZED,则返回 estimateSize() 的便捷方法,否则返回 -1。 |
default boolean | hasCharacteristics(int characteristics) | 如果此 Spliterator 的 features() 包含所有给定的特征,则返回 true。 |
boolean | tryAdvance(Consumer<? super T> action) | 如果存在剩余元素,则对其执行给定的操作,返回 true; 否则返回false。 |
SpliteratorT | trySplit() | 如果此 spliterator 可以分区,则返回一个 Spliterator 覆盖元素,从该方法返回时,该 Spliterator 不会被此 Spliterator 覆盖。 |
字段详细信息
CONCURRENT
static final int CONCURRENT
特征值表示元素源可以被多个线程安全地同时修改(允许添加、替换和/或删除)而无需外部同步。 如果是这样,Spliterator 应该有一个关于遍历期间修改的影响的文档化策略。
顶级 Spliterator 不应同时报告 CONCURRENT 和 SIZED,因为如果在遍历期间同时修改源,则有限大小(如果已知)可能会改变。 这样的 Spliterator 是不一致的,并且不能保证使用该 Spliterator 的任何计算。 如果子拆分大小已知并且在遍历时未反映对源的添加或删除,则子拆分器可能会报告 SIZED。
DISTINCT
static final int DISTINCT
特征值表示,对于每对遇到的元素 x, y, !x.equals(y)。 例如,这适用于基于 Set 的 Spliterator。
IMMUTABLE
static final int IMMUTABLE
表示元素源不能进行结构修改的特征值; 也就是说,元素不能被添加、替换或删除,因此在遍历过程中不会发生这种变化。 不报告 IMMUTABLE 或 CONCURRENT 的 Spliterator 应具有有关在遍历期间检测到的结构干扰的文档化策略(例如抛出 ConcurrentModificationException)。
NONNULL
static final int NONNULL
表示源保证遇到的元素不会为空的特征值。 (例如,这适用于大多数并发集合、队列和映射。)
ORDERED
static final int ORDERED
表示为元素定义相遇顺序的特征值。 如果是这样,则此 Spliterator 保证方法 trySplit() 拆分元素的严格前缀,该方法 tryAdvance(java.util.function.Consumer) 按前缀顺序逐个元素,以及该 forEachRemaining(java.util.function.Consumer) 按相遇顺序执行动作。
如果对应的 Collection#iterator 记录了订单,则 Collection 具有遇到订单。 如果是这样,遭遇顺序与记录的顺序相同。 否则,集合没有遇到顺序。
SIZED
static final int SIZED
特征值表示在遍历或拆分之前从estimateSize() 返回的值表示有限大小,在没有结构源修改的情况下,表示完整遍历将遇到的元素数量的精确计数。
SORTED
static final int SORTED
表示遇到顺序遵循定义的排序顺序的特征值。 如果是这样,则方法 getComparator() 返回关联的 Comparator,如果所有元素都是 Comparable 并且按其自然顺序排序,则返回 null。
报告 SORTED 的 Spliterator 也必须报告 ORDERED。
SUBSIZED
static final int SUBSIZED
特征值表示由 trySplit() 产生的所有拆分器都将是 SIZED 和 SUBSIZED。 (这意味着所有子拆分器,无论是直接的还是间接的,都将被调整大小。)
不按照 SUBSIZED 的要求报告 SIZED 的 Spliterator 是不一致的,并且不能保证使用该 Spliterator 的任何计算。
方法详情
tryAdvance
boolean tryAdvance(Consumer<? super T> action)
如果存在剩余元素,则对其执行给定的操作,返回 true; 否则返回假。 如果此 Spliterator 是 ORDERED,则按遇到顺序对下一个元素执行操作。 操作引发的异常将转发给调用者。
参数:
参数名称 | 参数描述 |
---|---|
action | 行动 |
返回:
如果在进入此方法时不存在剩余元素,则为 false,否则为 true。
Throws:
Throw名称 | Throw描述 |
---|---|
NullPointerException | 如果指定的操作为空 |
forEachRemaining
default void forEachRemaining(Consumer<? super T> action)
在当前线程中按顺序对每个剩余元素执行给定的操作,直到处理完所有元素或该操作引发异常。 如果此 Spliterator 是 ORDERED,则按遇到顺序执行操作。 操作引发的异常将转发给调用者。
参数:
参数名称 | 参数描述 |
---|---|
action | 行动 |
Throws:
Throw名称 | Throw描述 |
---|---|
NullPointerException | 如果指定的操作为空 |
trySplit
SpliteratorT trySplit()
如果此 spliterator 可以分区,则返回一个 Spliterator 覆盖元素,从该方法返回时,该 Spliterator 不会被此 Spliterator 覆盖。
如果此 Spliterator 是 ORDERED,则返回的 Spliterator 必须涵盖元素的严格前缀。
除非此 Spliterator 涵盖无限数量的元素,否则对 trySplit() 的重复调用最终必须返回 null。 在非空返回时:
- 在拆分之前为 estimateSize() 报告的值,在拆分之后,对于 this 和返回的 Spliterator,必须大于或等于 estimateSize(); 和
- 如果此 Spliterator 是 SUBSIZED,则此 spliterator 在拆分之前的estimateSize() 必须等于此 spliterator 的estimateSize() 与拆分后返回的 Spliterator 之和。
此方法可能出于任何原因返回 null,包括空虚、遍历开始后无法拆分、数据结构约束和效率考虑。
返回:
覆盖部分元素的 Spliterator,如果此 spliterator 无法拆分,则为 null
estimateSize
long estimateSize()
返回 forEachRemaining(java.util.function.Consumer) 遍历将遇到的元素数量的估计值,如果无限、未知或计算成本太高,则返回 Long#MAX_VALUE。
如果这个 Spliterator 是 SIZED 并且还没有被部分遍历或拆分,或者这个 Spliterator 是 SUBSIZED 并且还没有被部分遍历,那么这个估计必须是一个完整的遍历会遇到的元素的准确计数。 否则,这个估计可能是任意不准确的,但必须根据调用 trySplit() 的指定减少。
返回:
估计的大小,如果是无限的、未知的或计算成本太高,则为 Long.MAX_VALUE。
getExactSizeIfKnown
default long getExactSizeIfKnown()
如果此 Spliterator 为 SIZED,则返回 estimateSize() 的便捷方法,否则返回 -1。
返回:
确切的大小(如果已知),否则为 -1。
characteristics
int characteristics()
返回此 Spliterator 及其元素的一组特征。 结果表示为 ORDERED、DISTINCT、SORTED、SIZED、NONNULL、IMMUTABLE、CONCURRENT、SUBSIZED 的 ORed 值。 在给定拆分器上重复调用特性(),在调用 trySplit 之前或之间,应该总是返回相同的结果。
如果 Spliterator 报告了一组不一致的特征(从单个调用或跨多个调用返回的特征),则无法保证使用此 Spliterator 的任何计算。
返回:
特征的表示
hasCharacteristics
default boolean hasCharacteristics(int characteristics)
如果此 Spliterator 的 features() 包含所有给定的特征,则返回 true。
参数:
参数名称 | 参数描述 |
---|---|
characteristics | 要检查的特征 |
返回:
如果所有指定的特征都存在,则为 true,否则为 false
getComparator
default Comparator<? super T> getComparator()
如果此 Spliterator 的源由 Comparator 排序,则返回该 Comparator。 如果源在 Comparable 中已排序,则返回 null。 否则,如果源未排序,则抛出 IllegalStateException。
返回:
比较器,如果元素按自然顺序排序,则返回 null。
Throws:
Throw名称 | Throw描述 |
---|---|
IllegalStateException | 如果分离器没有报告 SORTED 的特征。 |