-
- 参数类型
-
T- 此Spliter的返回元素的类型
- All Known Subinterfaces:
-
Spliterator.OfDouble,Spliterator.OfInt,Spliterator.OfLong,Spliterator.OfPrimitive<T,T_CONS,T_SPLITR>
- 所有已知实现类:
-
Spliterators.AbstractDoubleSpliterator,Spliterators.AbstractIntSpliterator,Spliterators.AbstractLongSpliterator,Spliterators.AbstractSpliterator
public interface Spliterator<T>用于遍历和分割源的元素的对象。 Spliterator覆盖的元素的来源可以是例如阵列,Collection,IO通道或生成器函数。分割器可以逐个遍历元素(
tryAdvance())或批量(forEachRemaining())。分割器还可以将其一些元素(使用
trySplit()) 分割为另一个分割器,以在可能的并行操作中使用。 使用不能分割的Spliter的操作或者以非常不平衡或低效的方式进行的操作不太可能受益于并行性。 穿透和分流排气元件; 每个Spliterator仅对单个批量计算有用。甲Spliterator还报告一组
characteristics()选自其结构,源极和元件的ORDERED,DISTINCT,SORTED,SIZED,NONNULL,IMMUTABLE,CONCURRENT,和SUBSIZED。 这些可以由Spliterator客户端使用来控制,专门化或简化计算。 例如,Collection的Spliterator将报告SIZED的Spliterator将报告DISTINCT,并且SortedSet的Spliterator也将报告SORTED。 特性报告为简单的单位位。 一些特征还限制了方法行为; 例如,如果ORDERED,遍历方法必须符合其记录的顺序。 未来可能会定义新特性,因此实现者不应将含义分配给未列出的值。A Spliterator that does not report
IMMUTABLEorCONCURRENTis expected to have a documented policy concerning: when the spliterator binds to the element source; and detection of structural interference of the element source detected after binding. 后期绑定的 Spliterator在首次遍历,第一次拆分或第一个查询时针对估计大小而不是在创建Spliter时绑定到元素的来源。 没有晚期绑定的拼接器在构造或首次调用任何方法时绑定到元素的来源。 在绑定之前对源进行的修改在Spliter运行时被反映。 绑定后,如果检测到结构性干扰,尽力而为,应该抛出ConcurrentModificationException。 这样做的分割器称为故障快速 。 分割器的批量遍历方法(forEachRemaining())可以优化遍历并检查所有元素已经遍历之后的结构干扰,而不是立即检查每个元素并失败。分配器可以通过
estimateSize()方法提供剩余元素数量的估计。 理想情况下,如特征SIZED所反映的,该值与在成功遍历中遇到的元素的数量完全对应。 然而,即使不完全知道,估计值对于在源上执行的操作仍然可能是有用的,例如有助于确定是否优选进一步分割或者顺序地遍历剩余的元素。尽管它们在并行算法中具有明显的实用性,但拼接器并不期望是线程安全的; 相反,使用分割器的并行算法的实现应该确保分割器一次只被一个线程使用。 这通常是通过串行线程限制来获得的,这通常是通过递归分解工作的典型并行算法的自然结果。 调用
trySplit()的线程可能会将返回的Spliterator移交给另一个线程,而该线程又可以遍历或进一步拆分该分割器。 如果两个或多个线程在同一个分割器上同时运行,则分割和遍历的行为是未定义的。 如果原始线程将一个分离器移离另一个线程进行处理,则最好是在tryAdvance()使用任何元素之前发生切换,因为某些保证(例如SIZED分配器的SIZED准确性)仅在遍历开始之前有效。的原始亚型特
Spliterator提供用于int,long,和double值。 子类型默认实现为tryAdvance(java.util.function.Consumer)和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.Consumer)和Spliterator.OfInt.forEachRemaining(java.util.function.Consumer)使用 。 使用基于拳击的方法tryAdvance()和forEachRemaining()进行原始值的遍历不影响遇到转换为框值的值的顺序。- API Note:
-
Spliterators,如
Iterators,用于遍历源的元素。SpliteratorAPI旨在通过支持分解和单元素迭代来支持除顺序遍历之外的有效并行遍历。 另外,用于通过分割器访问元件的协议被设计为比Iterator施加更小的每元件开销,并且避免为具有hasNext()和next()单独方法所涉及的固有竞争。对于可变源,如果在Striterator绑定到其数据源的时间与遍历结束之间,源在结构上受到干扰(添加,替换或删除的元素),则可能会发生任意和非确定性行为。 例如,当使用
java.util.stream框架时,这种干扰将产生任意的非确定性结果。源的结构干扰可以通过以下方式进行管理(大概顺序为减少的可取性):
- 来源不能在结构上受到干扰。
例如,CopyOnWriteArrayList的一个实例是一个不可变的来源。 从源头创建的IMMUTABLE报告了IMMUTABLE的特征。 - 源代码管理并发修改。
例如,ConcurrentHashMap的密钥集是并发源。 从源创建的CONCURRENT报告了一个CONCURRENT的特征。 - 可变源提供后期绑定和故障切换快速分割器。
后期约束使窗口缩小,在此期间干扰可影响计算; 故障快速检测在尽力而为的基础上,遍历开始后发生结构性干扰,并抛出ConcurrentModificationException。 例如,ArrayList和JDK中的许多其他非并发的Collection类,提供了后期绑定,故障快速拼接器。 - 可变源提供了一个非后期绑定但是故障快速的分割器。
由于潜在的干扰窗口较大,源会增加投掷ConcurrentModificationException的可能性。 - 可变源提供后期绑定和非故障快速的分割器。
由于没有检测到干扰,因此源头在穿越开始后会产生任意的非确定性行为。 - 可变源提供非后期绑定和非故障快速的分割器。
来源会增加任意非确定性行为的风险,因为在建设后可能会发生非检测到的干扰。
例。 这是一个类(不是非常有用的,除了说明),它维护一个数组,其中实际数据保存在偶数位置,而不相关的标签数据保存在奇数位置。 它的Spliterator忽略标签。
class TaggedArray<T> { private final Object[] elements; // immutable after construction TaggedArray(T[] data, Object[] tags) { int size = data.length; if (tags.length != size) throw new IllegalArgumentException(); this.elements = new Object[2 * size]; for (int i = 0, j = 0; i < size; ++i) { elements[j++] = data[i]; elements[j++] = tags[i]; } } public Spliterator<T> spliterator() { return new TaggedArraySpliterator<>(elements, 0, elements.length); } static class TaggedArraySpliterator<T> implements Spliterator<T> { private final Object[] array; private int origin; // current index, advanced on split or traversal private final int fence; // one past the greatest index TaggedArraySpliterator(Object[] array, int origin, int fence) { this.array = array; this.origin = origin; this.fence = fence; } public void forEachRemaining(Consumer<? super T> action) { for (; origin < fence; origin += 2) action.accept((T) array[origin]); } public boolean tryAdvance(Consumer<? super T> action) { if (origin < fence) { action.accept((T) array[origin]); origin += 2; return true; } else // cannot advance return false; } public Spliterator<T> trySplit() { int lo = origin; // divide range in half int mid = ((lo + fence) >>> 1) & ~1; // force midpoint to be even if (lo < mid) { // split out left half origin = mid; // reset this Spliterator's origin return new TaggedArraySpliterator<>(array, lo, mid); } else // too small to split return null; } public long estimateSize() { return (long)((fence - origin) / 2); } public int characteristics() { return ORDERED | SIZED | IMMUTABLE | SUBSIZED; } } }例如,并行计算框架(例如
java.util.stream软件包)将如何在并行计算中使用Spliterator,这里是实现相关联的并行forEach的一种方法,它说明了分解子任务的主要用法,直到估计工作量足够小以顺序执行。 这里我们假设子任务处理的顺序并不重要; 不同的(分叉)任务可以进一步拆分并以未确定的顺序处理元素。 此示例使用CountedCompleter; 类似的用法适用于其他并行任务构造。static <T> void parEach(TaggedArray<T> a, Consumer<T> action) { Spliterator<T> s = a.spliterator(); long targetBatchSize = s.estimateSize() / (ForkJoinPool.getCommonPoolParallelism() * 8); new ParEach(null, s, action, targetBatchSize).invoke(); } static class ParEach<T> extends CountedCompleter<Void> { final Spliterator<T> spliterator; final Consumer<T> action; final long targetBatchSize; ParEach(ParEach<T> parent, Spliterator<T> spliterator, Consumer<T> action, long targetBatchSize) { super(parent); this.spliterator = spliterator; this.action = action; this.targetBatchSize = targetBatchSize; } public void compute() { Spliterator<T> sub; while (spliterator.estimateSize() > targetBatchSize && (sub = spliterator.trySplit()) != null) { addToPendingCount(1); new ParEach<>(this, sub, action, targetBatchSize).fork(); } spliterator.forEachRemaining(action); propagateCompletion(); } } - 来源不能在结构上受到干扰。
- Implementation Note:
-
如果布尔系统属性
org.openjdk.java.util.stream.tripwire设置为true则在对原始子类型专用化进行操作时,如果出现基本值的true则会报告诊断警告。 - 从以下版本开始:
- 1.8
- 另请参见:
-
Collection
-
-
Nested Class Summary
Nested Classes Modifier and Type 接口 描述 static interfaceSpliterator.OfDouble一个专门针对double值的double。static interfaceSpliterator.OfInt一个专门为int值的int。static interfaceSpliterator.OfLong一个专门针对long值的long。static interfaceSpliterator.OfPrimitive<T,T_CONS,T_SPLITR extends Spliterator.OfPrimitive<T,T_CONS,T_SPLITR>>专门针对原始价值观的Spliterator。
-
Field Summary
Fields Modifier and Type Field 描述 static intCONCURRENT特征值表示可以通过多个线程安全同时修改元素源(允许添加,替换和/或删除),而无需外部同步。static intDISTINCT特性值这标志着,对于每对遇到的元件x, y,!x.equals(y)。static intIMMUTABLE特征值表示元素源不能在结构上进行修改; 也就是说,不能添加,替换或删除元素,因此在遍历过程中不会发生这种更改。static intNONNULL特征值表示源保证遇到的元素不会是null。static intORDERED特征值表示为元素定义遇到顺序。static intSIZED表示在遍历或分割之前从estimateSize()返回的值的特征值表示在没有结构源修改的情况下表示完全遍历将遇到的元素数量的精确计数的有限大小。static intSORTED特征值表示遇到的顺序遵循定义的排序顺序。static intSUBSIZED
-
方法摘要
所有方法 接口方法 抽象方法 Default Methods Modifier and Type 方法 描述 intcharacteristics()返回此Spliterator及其元素的一组特征。longestimateSize()返回forEachRemaining(java.util.function.Consumer<? super T>)遍历将遇到的元素数量的估计,如果无穷大,未知数或计算成本太高,则返回Long.MAX_VALUE。default voidforEachRemaining(Consumer<? super T> action)在当前线程中依次执行每个剩余元素的给定操作,直到所有元素都被处理或动作引发异常。default Comparator<? super T>getComparator()如果这个Spliterator的来源是SORTED由Comparator,则返回Comparator。default longgetExactSizeIfKnown()default booleanhasCharacteristics(int characteristics)如果此Spliterator的characteristics()包含所有给定的特征,则返回true。booleantryAdvance(Consumer<? super T> action)如果剩下的元素存在,执行给定的操作,返回true; 否则返回false。Spliterator<T>trySplit()如果此分割器可以被分区,返回一个包含元素的Spliter,当从该方法返回时,它不会被该Spliter所覆盖。
-
-
-
字段详细信息
-
ORDERED
static final int ORDERED
特征值表示为元素定义遇到顺序。 如果是这样,则该Spliterator保证方法trySplit()以前缀顺序将元素的严格前缀(方法tryAdvance(java.util.function.Consumer<? super T>)按步骤按一个元素) 拆分 ,并且forEachRemaining(java.util.function.Consumer<? super T>)以遇到的顺序执行操作。A
Collection有相应的订单,如果相应的Collection.iterator()文件订单。 如果是这样,遇到的订单与记录的订单相同。 否则,集合没有遇到订单。- API Note:
-
对于任何
List,遇到的订单保证是升序索引顺序。 但是,对于基于哈希的集合,如HashSet,没有保证任何顺序。 报告ORDERED的分割器的客户端将在非交换并行计算中保留排序约束。 - 另请参见:
- Constant Field Values
-
DISTINCT
static final int DISTINCT
特性值这标志着,对于每对遇到的元件x, y,!x.equals(y)。 这适用于基于Set的Spliterator 。- 另请参见:
- Constant Field Values
-
SORTED
static final int SORTED
特征值表示遇到的顺序遵循定义的排序顺序。 如果是,方法getComparator()返回相关的比较器,或null如果所有元素是Comparable,并按其自然排序进行排序。报告
SORTED也必须报告ORDERED。- API Note:
-
在JDK中实现
NavigableSet或SortedSet的Collection类的分配器报告SORTED。 - 另请参见:
- Constant Field Values
-
SIZED
static final int SIZED
表示在遍历或分割之前从estimateSize()返回的值的特征值表示在没有结构源修改的情况下表示完全遍历将遇到的元素数量的精确计数的有限大小。- API Note:
-
大多数集合的分割器,涵盖
Collection所有元素报告此特征。 子分割器(例如HashSet的子分割器 )覆盖了一组子元素并近似于其报告的大小。 - 另请参见:
- Constant Field Values
-
NONNULL
static final int NONNULL
特征值表示源保证遇到的元素不会是null。 (这适用于大多数并发集合,队列和映射)。- 另请参见:
- Constant Field Values
-
IMMUTABLE
static final int IMMUTABLE
特征值表示元素源不能在结构上进行修改; 也就是说,不能添加,替换或删除元素,因此在遍历过程中不会发生这种更改。 预计不会报告IMMUTABLE或CONCURRENT有关于在遍历期间检测到的结构性干扰的文档化策略(例如抛出ConcurrentModificationException)。- 另请参见:
- Constant Field Values
-
CONCURRENT
static final int CONCURRENT
特征值表示可以通过多个线程安全同时修改元素源(允许添加,替换和/或删除),而无需外部同步。 如果是这样,则Spliterator应该有一个关于在遍历期间修改影响的文件化策略。顶级Spliterator不应同时报告
CONCURRENT和SIZED,因为如果已知的有限大小可能会在遍历期间同时修改源时发生更改。 这样的分割器是不一致的,并且不能保证使用该分割器的任何计算。 子分割器可能会报告SIZED如果子分割大小是已知的,并且在遍历时不反映源的添加或删除。顶级Spliterator不应同时报告
CONCURRENT和IMMUTABLE,因为它们是互斥的。 这样的分割器是不一致的,并且不能保证使用该分割器的任何计算。 子程序可能会报告IMMUTABLE如果源的添加或删除在运行时不被反映。- API Note:
- 大多数并发收藏集保持一致性政策,保证在Spliterator构建点存在的元素的准确性,但可能不反映随后的添加或删除。
- 另请参见:
- Constant Field Values
-
SUBSIZED
static final int SUBSIZED
特征值这标志着从产生的所有SpliteratorstrySplit()将是既SIZED和SUBSIZED。 (这意味着所有的子代码器,无论是直接还是间接,都将是SIZED)根据SUBSIZED的要求不会报告
SIZED的SUBSIZED不一致,并且不能保证使用该Spliterator的任何计算。- API Note:
-
一些拼接器,例如用于近似平衡的二叉树的顶级拼接器,将报告
SIZED而不是SUBSIZED,因为通常知道整个树的大小,但不知道子树的确切大小。 - 另请参见:
- Constant Field Values
-
-
方法详细信息
-
tryAdvance
boolean tryAdvance(Consumer<? super T> action)
- 参数
-
action- 动作 - 结果
-
false如果在进入此方法时不存在剩余元素,否则为true。 - 异常
-
NullPointerException- 如果指定的动作为空
-
forEachRemaining
default void forEachRemaining(Consumer<? super T> action)
- 实现要求:
-
默认实现反复调用
tryAdvance(java.util.function.Consumer<? super T>),直到它返回false。 应尽可能覆盖。 - 参数
-
action- 行动 - 异常
-
NullPointerException- 如果指定的操作为空
-
trySplit
Spliterator<T> trySplit()
如果此分割器可以被分区,返回一个包含元素的Spliter,当从该方法返回时,它不会被该Spliter所覆盖。如果此Spliterator是
ORDERED,则返回的Spliterator必须覆盖元素的严格前缀。除非这个Spliterator包含无数的元素,否则重复调用
trySplit()必须最终返回null。 非空返回:- 在拆分之前报告的值为
estimateSize(),拆分后必须大于或等于estimateSize()为此和返回的Spliterator; 和 - 如果这Spliterator是
SUBSIZED,然后estimateSize()这个spliterator分裂之前必须等于总和estimateSize(),这和拆分后返回Spliterator。
该方法可能由于任何原因返回
null,包括空虚,遍历开始后无法拆分,数据结构约束和效率考虑。- API Note:
-
理想的
trySplit方法(无遍历)将其元素精确地分成两半,从而实现平衡的并行计算。 许多离开这个理想的人仍然是非常有效的; 例如,仅近似分裂近似平衡的树,或者对于叶节点可以包含一个或两个元素的树,不能进一步分割这些节点。 然而,平衡和/或过度无效的trySplit力学的大偏差通常导致差的并行性能。 - 结果
-
一个
Spliterator涵盖了部分元素,或null如果此拼接器无法拆分
- 在拆分之前报告的值为
-
estimateSize
long estimateSize()
返回forEachRemaining(java.util.function.Consumer<? super T>)遍历将遇到的元素数量的估计值,如果无穷大,未知数或计算成本太高,则返回Long.MAX_VALUE。如果此Spliterator是
SIZED并且尚未部分遍历或拆分,或该Spliterator为SUBSIZED并且尚未部分遍历,则此估计必须是完整遍历将遇到的元素的精确计数。 否则,此估计可能是任意不准确的,但必须按照trySplit()的调用指定的方式减少 。- API Note:
- 即使不精确的估计通常是有用的并且计算成本低廉。 例如,近似平衡的二叉树的子拼接器可以返回将元素的数量估计为其父代的数量的一半的值; 如果根分割器不能保持准确的计数,则可以将尺寸估计为对应于其最大深度的两倍。
- 结果
-
估计的大小,或
Long.MAX_VALUE如果无限,未知或太贵的计算。
-
getExactSizeIfKnown
default long getExactSizeIfKnown()
- 实现要求:
-
如果Spliterator报告的特性为
SIZED,则默认实现返回estimateSize()的结果,estimateSize()返回-1。 - 结果
-
确切的大小,如果知道,其他
-1。
-
characteristics
int characteristics()
返回此Spliterator及其元素的一组特征。 结果从表示为或运算值ORDERED,DISTINCT,SORTED,SIZED,NONNULL,IMMUTABLE,CONCURRENT,SUBSIZED。 在给定的分配器之前或之前或之间调用trySplit重复调用characteristics()应始终返回相同的结果。如果Spliterator报告不一致的特征集(从单个调用返回的或多个调用返回的),则不能保证使用此Spliter的任何计算。
- API Note:
-
分裂之前的给定分配器的特性可能与分裂后的特性不同。
对于具体的例子看到的特性值
SIZED,SUBSIZED和CONCURRENT。 - 结果
- 特征的表征
-
hasCharacteristics
default boolean hasCharacteristics(int characteristics)
如果此Spliterator的characteristics()包含所有给定的特征,则返回true。- 实现要求:
- 如果给定特征的相应位被设置,默认实现将返回true。
- 参数
-
characteristics- 检查的特点 - 结果
-
true如果所有指定的特性都存在,否则为false
-
getComparator
default Comparator<? super T> getComparator()
如果这个Spliterator的来源是SORTED由Comparator,返回Comparator。 如果SORTED中的来源是SORTED ,则返回null。 否则,如果源不是SORTED,则抛出IllegalStateException。- 实现要求:
-
默认实现总是抛出
IllegalStateException。 - 结果
-
比较器,或
null如果元素按照自然顺序排序。 - 异常
-
IllegalStateException- 如果拼接器不报告SORTED的特征。
-
-