阅读(2329) (0)

鸿蒙OS Spliterator

2022-06-15 17:59:04 更新

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 的特征。