特征值 | 意义 |
---|---|
ORDERED | 分离器内部元素是按插入顺序排序的,如List |
DISTINCT | 分离器内部元素是不重复的,如Set |
SORTED | 分离器内部元素是有序的,如SortedSet |
SIZED | 表示分离器在遍历或拆分之前从estimateSize()返回的值表示有限大小,大多数集合有这个特性 |
NONNULL | 分离器内部元素是非null的 |
IMMUTABLE | 分离器内部元素是不可变的 |
CONCURREN | 分离器内部元素是可以被多个线程安全地同时修改,而无需外部同步 |
SUBSIZED | 表示分离器是被拆分出来的 |
方法名 | 作用 |
---|---|
boolean tryAdvance(Consumer action) | 如果存在剩余元素,则对其执行给定操作,并返回true,不存在剩余元素返回false |
Spliterator trySplit() | 如果此拆分器可以拆分,则返回一个包含元素的拆分器, 从该方法返回后,该拆分器将不包含这些拆分出去的元素 |
long estimateSize() | 返回forEachRemaining遍历将遇到的元素数的估计值, 如果无限、未知或计算成本太高,则返回Long#MAX_VALUE |
int characteristics() | 返回此拆分器及其元素的特征 |
Consumer 是一个函数式接口,里面只有一个accept方法,表示接收一个值处理后并返回一个值,Consumer源码可以看我这篇文章 Consumer
方法名 | 作用 |
---|---|
default void forEachRemaining(Consumer action) | 在当前线程中按顺序对每个剩余元素执行给定操作, 直到处理完所有元素或该操作引发异常为止,循环调用tryAdvance方法 |
default Comparator getComparator() | 此拆分器的特征是SORTED,则返回Comparator,如果是自然排序,返回null,如果特征是其他抛出异常 |
default long getExactSizeIfKnown() | 如果此拆分器的特征是SIZED,则执行estimateSize()并返回其返回值, 否则返回-1 |
default boolean hasCharacteristics(int characteristics) | 如果此拆分器的characteristics包含所有给定的特征,则返回true |
package java.util;
import java.util.function.Consumer;
import java.util.function.DoubleConsumer;
import java.util.function.IntConsumer;
import java.util.function.LongConsumer;
/**
* An object for traversing and partitioning elements of a source. The source
* of elements covered by a Spliterator could be, for example, an array, a
* {@link Collection}, an IO channel, or a generator function.
* 用于遍历和划分源元素的对象。拆分器覆盖的元素源可以是,
* 例如,数组、Collection、IO通道或生成器函数。
*
*
* A Spliterator may traverse elements individually ({@link
* #tryAdvance tryAdvance()}) or sequentially in bulk
* ({@link #forEachRemaining forEachRemaining()}).
* 拆分器可以单独遍历元素tryAdvance(),也可以批量遍历顺序元素forEachRemaining()。
*
*
*
*
*
A Spliterator may also partition off some of its elements (using
* {@link #trySplit}) as another Spliterator, to be used in
* possibly-parallel operations. Operations using a Spliterator that
* cannot split, or does so in a highly imbalanced or inefficient
* manner, are unlikely to benefit from parallelism. Traversal
* and splitting exhaust elements; each Spliterator is useful for only a single
* bulk computation.
* 拆分器也可以将它的一些元素(使用trySplit)划分为另一个拆分器,
* 以便在可能的并行操作中使用。
* 使用无法拆分的拆分器或以高度不平衡或低效的方式拆分的操作不太可能从并行性中获益。
* 遍历和拆分元件;每个拆分器仅用于单个批量计算。
*
*
*
*
A Spliterator also reports a set of {@link #characteristics()} of its
* structure, source, and elements from among {@link #ORDERED},
* {@link #DISTINCT}, {@link #SORTED}, {@link #SIZED}, {@link #NONNULL},
* {@link #IMMUTABLE}, {@link #CONCURRENT}, and {@link #SUBSIZED}. These may
* be employed by Spliterator clients to control, specialize or simplify
* computation. For example, a Spliterator for a {@link Collection} would
* report {@code SIZED}, a Spliterator for a {@link Set} would report
* {@code DISTINCT}, and a Spliterator for a {@link SortedSet} would also
* report {@code SORTED}. Characteristics are reported as a simple unioned bit
* set.
* 拆分器还从ORDERED、DISTINCT、SORTED、SIZED、NONNULL、IMMUTABLE、CONCURRENT和SUBSIZED
* 报告其结构、源和元素的一组characteristics()。
* 拆分器客户端可以使用这些工具来控制、专门化或简化计算。
* 例如,Collection的拆分器将报告size,Set的拆分器将报告DISTINCT,
* 而SortedSet的拆分器也将报告SORTED。特性报告为简单的联合位集。
*
*
*
*
*
*
* Some characteristics additionally constrain method behavior; for example if
* {@code ORDERED}, traversal methods must conform to their documented ordering.
* New characteristics may be defined in the future, so implementors should not
* assign meanings to unlisted values.
* 一些特性额外约束了方法行为;例如,如果ORDERED,遍历方法必须符合其文档化的顺序。
* 将来可能会定义新的特性,因此实现者不应该为未列出的值指定含义。
*
*
A Spliterator that does not report {@code IMMUTABLE} or
* {@code CONCURRENT} is 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. A
* late-binding Spliterator binds to the source of elements at the
* point of first traversal, first split, or first query for estimated size,
* rather than at the time the Spliterator is created. A Spliterator that is
* not late-binding binds to the source of elements at the point of
* construction or first invocation of any method. Modifications made to the
* source prior to binding are reflected when the Spliterator is traversed.
* After binding a Spliterator should, on a best-effort basis, throw
* {@link ConcurrentModificationException} if structural interference is
* detected. Spliterators that do this are called fail-fast. The
* bulk traversal method ({@link #forEachRemaining forEachRemaining()}) of a
* Spliterator may optimize traversal and check for structural interference
* after all elements have been traversed, rather than checking per-element and
* failing immediately.
* 不报告IMMUTABLE或CONCURRENT的拆分器应该有一个文档化的策略:
* 当拆分器绑定到元素源时;以及检测绑定后检测到的元素源的结构干扰。
* 后期绑定拆分器在第一次遍历、第一次拆分或第一次查询估计大小时绑定到元素源,
* 而不是在创建拆分器时绑定。未进行后期绑定的拆分器在任何方法的构造点或第一次调用点绑定到元素源。
* 在遍历拆分器时,会反映绑定之前对源所做的修改。
* 绑定后,如果检测到结构干扰,拆分器应尽最大努力抛出ConcurrentModificationException。
* 执行此操作的拆分器称为fail fast。
* 拆分器的批量遍历方法(forEachRemaining())可以优化遍历并在遍历所有元素后检查结构干涉,
* 而不是检查每个元素并立即失败。
*
*
*
*
*
*
Spliterators can provide an estimate of the number of remaining elements
* via the {@link #estimateSize} method. Ideally, as reflected in characteristic
* {@link #SIZED}, this value corresponds exactly to the number of elements
* that would be encountered in a successful traversal. However, even when not
* exactly known, an estimated value may still be useful to operations
* being performed on the source, such as helping to determine whether it is
* preferable to split further or traverse the remaining elements sequentially.
* 用作完成队列的队列通常是此服务专用的队列。
* 此队列被视为无界的--已完成任务的失败尝试queue.add操作将导致无法检索这些任务。
*
*
*
*
Despite their obvious utility in parallel algorithms, spliterators are not
* expected to be thread-safe; instead, implementations of parallel algorithms
* using spliterators should ensure that the spliterator is only used by one
* thread at a time. This is generally easy to attain via serial
* thread-confinement, which often is a natural consequence of typical
* parallel algorithms that work by recursive decomposition. A thread calling
* {@link #trySplit()} may hand over the returned Spliterator to another thread,
* which in turn may traverse or further split that Spliterator. The behaviour
* of splitting and traversal is undefined if two or more threads operate
* concurrently on the same spliterator. If the original thread hands a
* spliterator off to another thread for processing, it is best if that handoff
* occurs before any elements are consumed with {@link #tryAdvance(Consumer)
* tryAdvance()}, as certain guarantees (such as the accuracy of
* {@link #estimateSize()} for {@code SIZED} spliterators) are only valid before
* traversal has begun.
* 尽管拆分器在并行算法中具有明显的实用性,但它并不具有线程安全性;
* 相反,使用拆分器的并行算法的实现应该确保拆分器一次只能由一个线程使用。
* 这通常很容易通过串行线程限制实现,
* 这通常是通过递归分解工作的典型并行算法的自然结果。
* 调用trySplit()的线程可能会将返回的拆分器移交给另一个线程,
* 而另一个线程又可能遍历或进一步拆分该拆分器。
* 如果两个或多个线程同时在同一个拆分器上操作,
* 则拆分和遍历的行为是未定义的。
* 如果原始线程将拆分器交给另一个线程处理,
* 最好在使用tryAdvance(Consumer)使用任何元素之前进行切换,
* 因为某些保证(例如size拆分器的estimateSize()的准确性)仅在遍历开始之前有效。
*
*
*
*
*
*
Primitive subtype specializations of {@code Spliterator} are provided for
* {@link OfInt int}, {@link OfLong long}, and {@link OfDouble double} values.
* The subtype default implementations of
* {@link Spliterator#tryAdvance(java.util.function.Consumer)}
* and {@link Spliterator#forEachRemaining(java.util.function.Consumer)} box
* primitive values to instances of their corresponding wrapper class. Such
* boxing may undermine any performance advantages gained by using the primitive
* specializations. To avoid boxing, the corresponding primitive-based methods
* should be used. For example,
* {@link Spliterator.OfInt#tryAdvance(java.util.function.IntConsumer)}
* and {@link Spliterator.OfInt#forEachRemaining(java.util.function.IntConsumer)}
* should be used in preference to
* {@link Spliterator.OfInt#tryAdvance(java.util.function.Consumer)} and
* {@link Spliterator.OfInt#forEachRemaining(java.util.function.Consumer)}.
* Traversal of primitive values using boxing-based methods
* {@link #tryAdvance tryAdvance()} and
* {@link #forEachRemaining(java.util.function.Consumer) forEachRemaining()}
* does not affect the order in which the values, transformed to boxed values,
* are encountered.
* Spliterator的原语子类型专门化是为OfInt、OfLong和OfDouble值提供的。
* 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.Consumer)和
* Spliterator.OfInt#forEachRemaining(java.util.function.Consumer)。
* 使用基于装箱的方法tryAdvance和forEachRemaining(java.util.function.Consumer)
* 遍历基元值不会影响将值转换为装箱值的顺序。
*
*
*
*
*
*
*
*
* @apiNote
*
Spliterators, like {@code Iterator}s, are for traversing the elements of
* a source. The {@code Spliterator} API was designed to support efficient
* parallel traversal in addition to sequential traversal, by supporting
* decomposition as well as single-element iteration. In addition, the
* protocol for accessing elements via a Spliterator is designed to impose
* smaller per-element overhead than {@code Iterator}, and to avoid the inherent
* race involved in having separate methods for {@code hasNext()} and
* {@code next()}.
* 拆分器,如Iterator,用于遍历源代码的元素。Spliterator API通过支持分解和单元素迭代,
* 除了支持顺序遍历外,还支持高效的并行遍历。
* 此外,通过拆分器访问元素的协议被设计为比Iterator施加更小的每个元素开销,
* 并避免为hasNext()和next()使用单独的方法所涉及的固有竞争。
*
*
*
*
*
*
For mutable sources, arbitrary and non-deterministic behavior may occur if
* the source is structurally interfered with (elements added, replaced, or
* removed) between the time that the Spliterator binds to its data source and
* the end of traversal. For example, such interference will produce arbitrary,
* non-deterministic results when using the {@code java.util.stream} framework.
* 对于可变源,如果在拆分器绑定到其数据源和遍历结束之间源在结构上受到干扰(添加、替换或删除元素),
* 则可能会发生任意和非确定性行为。
* 例如,当使用java.util.stream框架时,这种干扰将产生任意的、不确定的结果。
*
*
*
*
Structural interference of a source can be managed in the following ways
* (in approximate order of decreasing desirability):
* 源的结构干扰可通过以下方式进行管理(按期望值递减的近似顺序):
*
*
* - The source cannot be structurally interfered with.
*
For example, an instance of
* {@link java.util.concurrent.CopyOnWriteArrayList} is an immutable source.
* A Spliterator created from the source reports a characteristic of
* {@code IMMUTABLE}.
* 不能从结构上干扰源。
* 例如,java.util.concurrent.CopyOnWriteArrayList的实例是一个不可变的源。
* 从源代码创建的拆分器报告IMMUTABLE的特征。
*
*
*
* - The source manages concurrent modifications.
*
For example, a key set of a {@link java.util.concurrent.ConcurrentHashMap}
* is a concurrent source. A Spliterator created from the source reports a
* characteristic of {@code CONCURRENT}.
* 源代码管理并发修改。例如,java.util.concurrent.ConcurrentHashMap的键集是一个并发源。
* 从源创建的拆分器报告 CONCURRENT的特征。
*
*
*
* - The mutable source provides a late-binding and fail-fast Spliterator.
*
Late binding narrows the window during which interference can affect
* the calculation; fail-fast detects, on a best-effort basis, that structural
* interference has occurred after traversal has commenced and throws
* {@link ConcurrentModificationException}. For example, {@link ArrayList},
* and many other non-concurrent {@code Collection} classes in the JDK, provide
* a late-binding, fail-fast spliterator.
* 可变源提供了一个后期绑定和故障快速拆分器。
* 后期绑定缩小了干扰可能影响计算的窗口;快速失效尽最大努力检测遍历开始后发生的结构干扰,
* 并抛出ConcurrentModificationException。
* 例如, ArrayList和JDK中的许多其他非并发Collection
* 类提供了一个后期绑定、快速失效的拆分器。
*
*
*
*
* - The mutable source provides a non-late-binding but fail-fast Spliterator.
*
The source increases the likelihood of throwing
* {@code ConcurrentModificationException} since the window of potential
* interference is larger.
* 可变源提供一个非后期绑定但快速失败的拆分器。
* 源增加了抛出ConcurrentModificationException的可能性,因为潜在干扰的窗口更大。
*
*
*
*
* - The mutable source provides a late-binding and non-fail-fast Spliterator.
*
The source risks arbitrary, non-deterministic behavior after traversal
* has commenced since interference is not detected.
*
* 可变源提供了一个后期绑定和非故障快速拆分器。
* 由于未检测到干扰,在遍历开始后,源可能会出现任意的、不确定的行为。
*
*
*
* - The mutable source provides a non-late-binding and non-fail-fast
* Spliterator.
*
The source increases the risk of arbitrary, non-deterministic behavior
* since non-detected interference may occur after construction.
*
* 可变源提供了一个非延迟绑定和非故障快速拆分器。
* 由于施工后可能会出现未检测到的干扰,
* 因此该源增加了任意、不确定行为的风险。
*
*
*
*
*
*
*
* Example. Here is a class (not a very useful one, except
* for illustration) that maintains an array in which the actual data
* are held in even locations, and unrelated tag data are held in odd
* locations. Its Spliterator ignores the tags.
* 例如,这里有一个类(除了图示之外,它不是一个非常有用的类),
* 它维护一个数组,其中实际数据保存在偶数位置,
* 而不相关的标记数据保存在奇数位置。它的拆分器忽略标记。
*
*
{@code
* class TaggedArray {
* 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 spliterator() {
* return new TaggedArraySpliterator<>(elements, 0, elements.length);
* }
*
* static class TaggedArraySpliterator implements Spliterator {
* 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 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;
* }
* }
* }}
*
*
*
* As an example how a parallel computation framework, such as the
* {@code java.util.stream} package, would use Spliterator in a parallel
* computation, here is one way to implement an associated parallel forEach,
* that illustrates the primary usage idiom of splitting off subtasks until
* the estimated amount of work is small enough to perform
* sequentially. Here we assume that the order of processing across
* subtasks doesn't matter; different (forked) tasks may further split
* and process elements concurrently in undetermined order. This
* example uses a {@link java.util.concurrent.CountedCompleter};
* similar usages apply to other parallel task constructions.
* 作为并行计算框架(如java.util.stream包)如何在并行计算中使用拆分器的示例,
* 下面是实现关联并行forEach的一种方法,这说明了将子任务分离,
* 直到估计的工作量小到足以按顺序执行为止的主要用法。
* 在这里,我们假设子任务之间的处理顺序无关紧要;
* 不同的(分叉的)任务可能会进一步拆分并以不确定的顺序并发处理元素。
* 这个例子使用了一个java.util.concurrent.CountedCompleter;
* 类似的用法也适用于其他并行任务结构。
*
*
*
*
{@code
* static void parEach(TaggedArray a, Consumer action) {
* Spliterator s = a.spliterator();
* long targetBatchSize = s.estimateSize() / (ForkJoinPool.getCommonPoolParallelism() * 8);
* new ParEach(null, s, action, targetBatchSize).invoke();
* }
*
* static class ParEach extends CountedCompleter {
* final Spliterator spliterator;
* final Consumer action;
* final long targetBatchSize;
*
* ParEach(ParEach parent, Spliterator spliterator,
* Consumer action, long targetBatchSize) {
* super(parent);
* this.spliterator = spliterator; this.action = action;
* this.targetBatchSize = targetBatchSize;
* }
*
* public void compute() {
* Spliterator sub;
* while (spliterator.estimateSize() > targetBatchSize &&
* (sub = spliterator.trySplit()) != null) {
* addToPendingCount(1);
* new ParEach<>(this, sub, action, targetBatchSize).fork();
* }
* spliterator.forEachRemaining(action);
* propagateCompletion();
* }
* }}
*
* @implNote
* If the boolean system property {@code org.openjdk.java.util.stream.tripwire}
* is set to {@code true} then diagnostic warnings are reported if boxing of
* primitive values occur when operating on primitive subtype specializations.
* 如果布尔系统属性org.openjdk.java.util.stream.tripwire设置为true,
* 则如果在操作基元子类型专门化时发生基元值装箱,则会报告诊断警告。
*
* @param the type of elements returned by this Spliterator
*
* @see Collection
* @since 1.8
*/
public interface Spliterator<T> {
/**
* If a remaining element exists, performs the given action on it,
* returning {@code true}; else returns {@code false}. If this
* Spliterator is {@link #ORDERED} the action is performed on the
* next element in encounter order. Exceptions thrown by the
* action are relayed to the caller.
* 如果存在剩余元素,则对其执行给定操作,返回true;否则返回false。
* 如果此拆分器是ORDERED,则操作将按遇到顺序在下一个元素上执行。
* 操作引发的异常将转发给调用方。
*
*
* @param action The action
* @return {@code false} if no remaining elements existed
* upon entry to this method, else {@code true}.
* 如果在进入此方法时不存在剩余元素false,否则true
* @throws NullPointerException if the specified action is null 如果指定的操作为空
*/
boolean tryAdvance(Consumer<? super T> action);
/**
* Performs the given action for each remaining element, sequentially in
* the current thread, until all elements have been processed or the action
* throws an exception. If this Spliterator is {@link #ORDERED}, actions
* are performed in encounter order. Exceptions thrown by the action
* are relayed to the caller.
* 在当前线程中按顺序对每个剩余元素执行给定操作,
* 直到处理完所有元素或该操作引发异常为止。
* 如果此拆分器为ORDERED,则将按遇到顺序执行操作。
* 操作引发的异常将转发给调用方。
*
* @implSpec
* The default implementation repeatedly invokes {@link #tryAdvance} until
* it returns {@code false}. It should be overridden whenever possible.
* 默认实现反复调用tryAdvance,直到返回false。只要有可能,就应该覆盖它。
*
* @param action The action
* @throws NullPointerException if the specified action is null
*/
default void forEachRemaining(Consumer<? super T> action) {
do { } while (tryAdvance(action));
}
/**
* If this spliterator can be partitioned, returns a Spliterator
* covering elements, that will, upon return from this method, not
* be covered by this Spliterator.
* 如果此拆分器可以分区,则返回一个包含元素的拆分器,
* 从该方法返回后,该拆分器将不包含这些元素。
*
* If this Spliterator is {@link #ORDERED}, the returned Spliterator
* must cover a strict prefix of the elements.
* 如果此拆分器为ORDERED,则返回的拆分器必须包含元素的严格前缀。
*
*
Unless this Spliterator covers an infinite number of elements,
* repeated calls to {@code trySplit()} must eventually return {@code null}.
* Upon non-null return:
* 除非此拆分器覆盖无限多个元素,否则对trySplit()的重复调用最终必须返回null
* 非空返回时:
*
*
*
*
* - the value reported for {@code estimateSize()} before splitting,
* must, after splitting, be greater than or equal to {@code estimateSize()}
* for this and the returned Spliterator; and
* 拆分前estimateSize()报告的值在拆分后必须大于或
* 等于此拆分器和返回的拆分器的estimateSize()和
*
*
*
*
* - if this Spliterator is {@code SUBSIZED}, then {@code estimateSize()}
* for this spliterator before splitting must be equal to the sum of
* {@code estimateSize()} for this and the returned Spliterator after
* splitting.
* 如果此拆分器为SUBSIZED,则拆分前此拆分器的estimateSize()
* 必须等于拆分后此拆分器的estimateSize()与返回的拆分器的estimateSize()之和。
*
*
*
*
* This method may return {@code null} for any reason,
* including emptiness, inability to split after traversal has
* commenced, data structure constraints, and efficiency
* considerations.
* 此方法可能出于任何原因返回null,
* 包括空、遍历开始后无法拆分、数据结构约束和效率考虑。
*
* @apiNote
* An ideal {@code trySplit} method efficiently (without
* traversal) divides its elements exactly in half, allowing
* balanced parallel computation. Many departures from this ideal
* remain highly effective; for example, only approximately
* splitting an approximately balanced tree, or for a tree in
* which leaf nodes may contain either one or two elements,
* failing to further split these nodes. However, large
* deviations in balance and/or overly inefficient {@code
* trySplit} mechanics typically result in poor parallel
* performance.
* 理想的trySplit方法有效地(无需遍历)将其元素精确地分成两半,
* 从而允许平衡的并行计算。
* 许多背离这一理想的做法仍然非常有效;
* 例如,仅近似拆分近似平衡树,或者对于叶节点可能包含一个或两个元素的树,
* 无法进一步拆分这些节点。
* 然而,平衡中的大偏差和/或过于低效的trySplit机制通常会导致较差的并行性能。
*
*
*
*
* @return a {@code Spliterator} covering some portion of the
* elements, or {@code null} if this spliterator cannot be split
* 一个Spliterator覆盖元素的某些部分,或者null如果这个Spliterator不能被拆分
*/
Spliterator<T> trySplit();
/**
* Returns an estimate of the number of elements that would be
* encountered by a {@link #forEachRemaining} traversal, or returns {@link
* Long#MAX_VALUE} if infinite, unknown, or too expensive to compute.
* 返回forEachRemaining遍历将遇到的元素数的估计值,
* 如果无限、未知或计算成本太高,则返回Long#MAX_VALUE
*
*
*
* If this Spliterator is {@link #SIZED} and has not yet been partially
* traversed or split, or this Spliterator is {@link #SUBSIZED} and has
* not yet been partially traversed, this estimate must be an accurate
* count of elements that would be encountered by a complete traversal.
* Otherwise, this estimate may be arbitrarily inaccurate, but must decrease
* as specified across invocations of {@link #trySplit}.
* 如果此拆分器为size且尚未部分遍历或拆分,或者此拆分器为SUBSIZED且尚未部分遍历,
* 则此估计值必须是完整遍历将遇到的元素的准确计数。
* 否则,此估计可能会任意不准确,但必须在调用trySplit时按规定减少。
*
*
*
* @apiNote
* Even an inexact estimate is often useful and inexpensive to compute.
* For example, a sub-spliterator of an approximately balanced binary tree
* may return a value that estimates the number of elements to be half of
* that of its parent; if the root Spliterator does not maintain an
* accurate count, it could estimate size to be the power of two
* corresponding to its maximum depth.
* 即使是不精确的估计也常常是有用的,而且计算起来也不昂贵。
* 例如,近似平衡二叉树的子拆分器可以返回一个值,
* 该值估计元素数为其父树元素数的一半;如果根拆分器没有保持精确的计数,
* 它可以将大小估计为与其最大深度对应的2的幂。
*
*
*
* @return the estimated size, or {@code Long.MAX_VALUE} if infinite,
* unknown, or too expensive to compute.
* 估计的大小,或Long.MAX_VALUE(如果无限、未知或计算成本太高)。
*/
long estimateSize();
/**
* Convenience method that returns {@link #estimateSize()} if this
* Spliterator is {@link #SIZED}, else {@code -1}.
* 方便方法,如果此拆分器为SIZED,则返回estimateSize(),否则返回-1
* @implSpec
* The default implementation returns the result of {@code estimateSize()}
* if the Spliterator reports a characteristic of {@code SIZED}, and
* {@code -1} otherwise.
* 如果拆分器报告特性size,则默认实现返回结果estimateSize(),否则返回结果-1
*
*
* @return the exact size, if known, else {@code -1}. 确切的大小,如果已知,则为-1
*/
default long getExactSizeIfKnown() {
return (characteristics() & SIZED) == 0 ? -1L : estimateSize();
}
/**
* Returns a set of characteristics of this Spliterator and its
* elements. The result is represented as ORed values from {@link
* #ORDERED}, {@link #DISTINCT}, {@link #SORTED}, {@link #SIZED},
* {@link #NONNULL}, {@link #IMMUTABLE}, {@link #CONCURRENT},
* {@link #SUBSIZED}. Repeated calls to {@code characteristics()} on
* a given spliterator, prior to or in-between calls to {@code trySplit},
* should always return the same result.
* 返回此拆分器及其元素的一组特征。结果表示为ORDERED、DISTINCT、
* SORTED、SIZED、NONNULL、IMMUTABLE、CONCURRENT、SUBSIZED中的OR值。
* 在调用trySplit之前或之间,在给定拆分器上重复调用characteristics(),应始终返回相同的结果。
*
*
*
*
*
* If a Spliterator reports an inconsistent set of
* characteristics (either those returned from a single invocation
* or across multiple invocations), no guarantees can be made
* about any computation using this Spliterator.
* 如果拆分器报告一组不一致的特征(从单个调用或多个调用返回的特征),
* 则无法保证使用此拆分器进行任何计算。
*
*
*
*
* @apiNote The characteristics of a given spliterator before splitting
* may differ from the characteristics after splitting. For specific
* examples see the characteristic values {@link #SIZED}, {@link #SUBSIZED}
* and {@link #CONCURRENT}.
* 拆分前给定拆分器的特性可能与拆分后的特性不同。
* 有关具体示例,请参见特征值SIZED、SUBSIZED和CONCURRENT
*
*
*
* @return a representation of characteristics 特征的表现
*/
int characteristics();
/**
* Returns {@code true} if this Spliterator's {@link
* #characteristics} contain all of the given characteristics.
* 如果此拆分器的characteristics包含所有给定的特征,则返回true
*
* @implSpec
* The default implementation returns true if the corresponding bits
* of the given characteristics are set.
* 如果设置了给定特征的对应位,则默认实现返回true。
*
* @param characteristics the characteristics to check for 要检查的特征
* @return {@code true} if all the specified characteristics are present,
* else {@code false} 如果所有指定的特征都存在返回true,则返回false
*/
default boolean hasCharacteristics(int characteristics) {
return (characteristics() & characteristics) == characteristics;
}
/**
* If this Spliterator's source is {@link #SORTED} by a {@link Comparator},
* returns that {@code Comparator}. If the source is {@code SORTED} in
* {@linkplain Comparable natural order}, returns {@code null}. Otherwise,
* if the source is not {@code SORTED}, throws {@link IllegalStateException}.
* 如果此拆分器的源代码是由Comparator排序的SORTED,则返回该Comparator。
* 如果源是SORTED中的Comparable自然排序,则返回null。
* 否则,如果源代码不是SORTED,则抛出IllegalStateException
*
* @implSpec
* The default implementation always throws {@link IllegalStateException}.
* 默认实现总是抛出IllegalStateException
*
* @return a Comparator, or {@code null} if the elements are sorted in the
* natural order. 比较器,如果元素按自然顺序排序,则为null
* @throws IllegalStateException if the spliterator does not report
* a characteristic of {@code SORTED}. 如果拆分器没有报告SORTED的特征。
*/
default Comparator<? super T> getComparator() {
throw new IllegalStateException();
}
/**
* Characteristic value signifying that an encounter order is defined for
* elements. If so, this Spliterator guarantees that method
* {@link #trySplit} splits a strict prefix of elements, that method
* {@link #tryAdvance} steps by one element in prefix order, and that
* {@link #forEachRemaining} performs actions in encounter order.
* 表示为元素定义了相遇顺序的特征值。
* 如果是这样,这个拆分器保证方法trySplit拆分元素的严格前缀,
* 方法tryAdvance按前缀顺序步进一个元素,并且forEachRemaining按遭遇顺序执行操作。
*
*
*
*
* A {@link Collection} has an encounter order if the corresponding
* {@link Collection#iterator} documents an order. If so, the encounter
* order is the same as the documented order. Otherwise, a collection does
* not have an encounter order.
* 如果对应的Collection#iterator记录了一个顺序,则Collection有一个遭遇顺序。
* 如果是这样,遭遇顺序与记录的顺序相同。否则,集合没有遭遇顺序。
*
* @apiNote Encounter order is guaranteed to be ascending index order for
* any {@link List}. But no order is guaranteed for hash-based collections
* such as {@link HashSet}. Clients of a Spliterator that reports
* {@code ORDERED} are expected to preserve ordering constraints in
* non-commutative parallel computations.
* 遭遇顺序保证为任何List的索引升序。但是,对于基于散列的集合,例如HashSet,
* 没有顺序保证。报告ORDERED的拆分器的客户端应在非交换并行计算中保留排序约束。
*
*
*/
public static final int ORDERED = 0x00000010;
/**
* Characteristic value signifying that, for each pair of
* encountered elements {@code x, y}, {@code !x.equals(y)}. This
* applies for example, to a Spliterator based on a {@link Set}.
* 表示遇到的每对元素x,y,
* !x.equals(y)的特征值。例如,这适用于基于Set的拆分器。
*
*
*/
public static final int DISTINCT = 0x00000001;
/**
* Characteristic value signifying that encounter order follows a defined
* sort order. If so, method {@link #getComparator()} returns the associated
* Comparator, or {@code null} if all elements are {@link Comparable} and
* are sorted by their natural ordering.
* 表示相遇顺序遵循定义的排序顺序的特征值。
* 如果是,方法getComparator()返回关联的比较器,
* 如果所有元素都是Comparable并按其自然顺序排序,
* 则返回null
*
*
*
* A Spliterator that reports {@code SORTED} must also report
* {@code ORDERED}.
* 报告SORTED的拆分器也必须报告ORDERED
*
* @apiNote The spliterators for {@code Collection} classes in the JDK that
* implement {@link NavigableSet} or {@link SortedSet} report {@code SORTED}.
* JDK中实现NavigableSet或SortedSet的Collection类的拆分器报告SortedSet
*
*
*/
public static final int SORTED = 0x00000004;
/**
* Characteristic value signifying that the value returned from
* {@code estimateSize()} prior to traversal or splitting represents a
* finite size that, in the absence of structural source modification,
* represents an exact count of the number of elements that would be
* encountered by a complete traversal.
* 特征值,表示在遍历或拆分之前从estimateSize()返回的值表示有限大小,
* 在没有结构源修改的情况下,表示完整遍历将遇到的元素数的精确计数。
*
* @apiNote Most Spliterators for Collections, that cover all elements of a
* {@code Collection} report this characteristic. Sub-spliterators, such as
* those for {@link HashSet}, that cover a sub-set of elements and
* approximate their reported size do not.
* 大多数集合的拆分器,覆盖了Collection的所有元素,都报告了这个特性。
* 子拆分器,例如HashSet的子拆分器,覆盖了元素的子集合,
* 并且近似于它们报告的大小,但不包含这些子拆分器。
*
*
*/
public static final int SIZED = 0x00000040;
/**
* Characteristic value signifying that the source guarantees that
* encountered elements will not be {@code null}. (This applies,
* for example, to most concurrent collections, queues, and maps.)
* 表示源保证遇到的元素不为null的特征值。
* (例如,这适用于大多数并发集合、队列和映射。)
*
*
*/
public static final int NONNULL = 0x00000100;
/**
* Characteristic value signifying that the element source cannot be
* structurally modified; that is, elements cannot be added, replaced, or
* removed, so such changes cannot occur during traversal. A Spliterator
* that does not report {@code IMMUTABLE} or {@code CONCURRENT} is expected
* to have a documented policy (for example throwing
* {@link ConcurrentModificationException}) concerning structural
* interference detected during traversal.
* 表示元素源在结构上无法修改的特征值;
* 也就是说,不能添加、替换或删除元素,因此在遍历过程中不会发生此类更改。
* 对于不报告IMMUTABLE或CONCURRENT的拆分器,
* 应具有与遍历期间检测到的结构干扰有关的文档化策略
* (例如抛出ConcurrentModificationException)
*
*
*
*/
public static final int IMMUTABLE = 0x00000400;
/**
* Characteristic value signifying that the element source may be safely
* concurrently modified (allowing additions, replacements, and/or removals)
* by multiple threads without external synchronization. If so, the
* Spliterator is expected to have a documented policy concerning the impact
* of modifications during traversal.
* 特征值,表示可以由多个线程安全地同时修改元素源(允许添加、替换和/或删除),
* 而无需外部同步。
* 如果是这样的话,拆分器应该有一个关于遍历期间修改影响的文档化策略。
*
*
*
* A top-level Spliterator should not report both {@code CONCURRENT} and
* {@code SIZED}, since the finite size, if known, may change if the source
* is concurrently modified during traversal. Such a Spliterator is
* inconsistent and no guarantees can be made about any computation using
* that Spliterator. Sub-spliterators may report {@code SIZED} if the
* sub-split size is known and additions or removals to the source are not
* reflected when traversing.
* 顶级拆分器不应同时报告CONCURRENT和SIZED,因为如果在遍历过程中同时修改源,
* 有限大小(如果已知)可能会改变。
* 这样的拆分器是不一致的,不能保证使用该拆分器进行任何计算。
* 如果子拆分大小已知,并且在遍历时未反映对源的添加或删除,
* 则子拆分器可能会报告size
*
*
*
*
A top-level Spliterator should not report both {@code CONCURRENT} and
* {@code IMMUTABLE}, since they are mutually exclusive. Such a Spliterator
* is inconsistent and no guarantees can be made about any computation using
* that Spliterator. Sub-spliterators may report {@code IMMUTABLE} if
* additions or removals to the source are not reflected when traversing.
* 顶级拆分器不应同时报告CONCURRENT和IMMUTABLE,因为它们是互斥的。
* 这样的拆分器是不一致的,不能保证使用该拆分器进行任何计算。
* 如果在遍历时未反映对源的添加或删除,
* 子拆分器可能会报告IMMUTABLE
*
* @apiNote Most concurrent collections maintain a consistency policy
* guaranteeing accuracy with respect to elements present at the point of
* Spliterator construction, but possibly not reflecting subsequent
* additions or removals.
* 大多数并发集合都维护一个一致性策略,
* 保证在拆分器构造时存在的元素的准确性,但可能不反映后续的增加或删除。
*/
public static final int CONCURRENT = 0x00001000;
/**
* Characteristic value signifying that all Spliterators resulting from
* {@code trySplit()} will be both {@link #SIZED} and {@link #SUBSIZED}.
* (This means that all child Spliterators, whether direct or indirect, will
* be {@code SIZED}.)
* 表示由trySplit()生成的所有拆分器将同时为SIZED和SUBSIZED的特征值。
* (这意味着所有子拆分器,无论是直接的还是间接的,都将是SIZED)
*
*
*
* A Spliterator that does not report {@code SIZED} as required by
* {@code SUBSIZED} is inconsistent and no guarantees can be made about any
* computation using that Spliterator.
* 不按照SUBSIZED的要求报告SIZED的拆分器是不一致的,
* 并且不能保证使用该拆分器进行任何计算。
*
*
*
* @apiNote Some spliterators, such as the top-level spliterator for an
* approximately balanced binary tree, will report {@code SIZED} but not
* {@code SUBSIZED}, since it is common to know the size of the entire tree
* but not the exact sizes of subtrees.
* 一些拆分器,例如近似平衡二叉树的顶级拆分器,将报告SIZED而不是SUBSIZED,
* 因为通常知道整个树的大小,但不知道子树的确切大小。
*
*
*/
public static final int SUBSIZED = 0x00004000;
/**
* A Spliterator specialized for primitive values.
* 专门用于基本值的拆分器。
*
* @param the type of elements returned by this Spliterator. The
* type must be a wrapper type for a primitive type, such as {@code Integer}
* for the primitive {@code int} type.
* 此拆分器返回的元素类型。该类型必须是基元类型的包装器类型,
* 例如基元int类型的Integer
*
* @param the type of primitive consumer. The type must be a
* primitive specialization of {@link java.util.function.Consumer} for
* {@code T}, such as {@link java.util.function.IntConsumer} for
* {@code Integer}.
* 原始消费者的类型。类型必须是T的java.util.function.Consumer的原语专门化,
* 例如Integer的java.util.function.IntConsumer
*
*
* @param the type of primitive Spliterator. The type must be
* a primitive specialization of Spliterator for {@code T}, such as
* {@link Spliterator.OfInt} for {@code Integer}.
* 基本拆分器的类型。该类型必须是T的拆分器的原语专门化,
* 例如Integer的Spliterator.OfInt
*
* @see Spliterator.OfInt
* @see Spliterator.OfLong
* @see Spliterator.OfDouble
* @since 1.8
*/
public interface OfPrimitive<T, T_CONS, T_SPLITR extends Spliterator.OfPrimitive<T, T_CONS, T_SPLITR>>
extends Spliterator<T> {
@Override
T_SPLITR trySplit();
/**
* If a remaining element exists, performs the given action on it,
* returning {@code true}; else returns {@code false}. If this
* Spliterator is {@link #ORDERED} the action is performed on the
* next element in encounter order. Exceptions thrown by the
* action are relayed to the caller.
* 如果存在剩余元素,则对其执行给定操作,返回true,否则返回false。
* 如果此拆分器是ORDERED,则操作将按遇到顺序在下一个元素上执行。
* 操作引发的异常将转发给调用方。
*
* @param action The action
* @return {@code false} if no remaining elements existed
* upon entry to this method, else {@code true}.
* 如果在进入此方法时不存在剩余元素返回false,否则返回true
* @throws NullPointerException if the specified action is null
*/
@SuppressWarnings("overloads")
boolean tryAdvance(T_CONS action);
/**
* Performs the given action for each remaining element, sequentially in
* the current thread, until all elements have been processed or the
* action throws an exception. If this Spliterator is {@link #ORDERED},
* actions are performed in encounter order. Exceptions thrown by the
* action are relayed to the caller.
* 在当前线程中按顺序对每个剩余元素执行给定操作,直到处理完所有元素或该操作引发异常为止。
* 如果此拆分器为ORDERED,则将按遇到顺序执行操作。由动作被转发给调用者。
*
* @implSpec
* The default implementation repeatedly invokes {@link #tryAdvance}
* until it returns {@code false}. It should be overridden whenever
* possible.
* 默认实现反复调用tryAdvance,直到返回false。只要有可能,就应该覆盖它。
*
* @param action The action
* @throws NullPointerException if the specified action is null
*/
@SuppressWarnings("overloads")
default void forEachRemaining(T_CONS action) {
do { } while (tryAdvance(action));
}
}
/**
* A Spliterator specialized for {@code int} values.
* 专用于int值的拆分器。
* @since 1.8
*/
public interface OfInt extends OfPrimitive<Integer, IntConsumer, OfInt> {
@Override
OfInt trySplit();
@Override
boolean tryAdvance(IntConsumer action);
@Override
default void forEachRemaining(IntConsumer action) {
do { } while (tryAdvance(action));
}
/**
* {@inheritDoc}
* @implSpec
* If the action is an instance of {@code IntConsumer} then it is cast
* to {@code IntConsumer} and passed to
* {@link #tryAdvance(java.util.function.IntConsumer)}; otherwise
* the action is adapted to an instance of {@code IntConsumer}, by
* boxing the argument of {@code IntConsumer}, and then passed to
* {@link #tryAdvance(java.util.function.IntConsumer)}.
* 如果该操作是IntConsumer的实例,则将其强制转换为IntConsumer,
* 并传递给tryAdvance(java.util.function.IntConsumer);
* 否则,通过将IntConsumer的参数装箱,操作将适应于IntConsumer的实例,
* 然后传递给tryAdvance(java.util.function.IntConsumer)
*
*/
@Override
default boolean tryAdvance(Consumer<? super Integer> action) {
if (action instanceof IntConsumer) {
return tryAdvance((IntConsumer) action);
}
else {
if (Tripwire.ENABLED)
Tripwire.trip(getClass(),
"{0} calling Spliterator.OfInt.tryAdvance((IntConsumer) action::accept)");
return tryAdvance((IntConsumer) action::accept);
}
}
/**
* {@inheritDoc}
* @implSpec
* If the action is an instance of {@code IntConsumer} then it is cast
* to {@code IntConsumer} and passed to
* {@link #forEachRemaining(java.util.function.IntConsumer)}; otherwise
* the action is adapted to an instance of {@code IntConsumer}, by
* boxing the argument of {@code IntConsumer}, and then passed to
* {@link #forEachRemaining(java.util.function.IntConsumer)}.
* 如果该操作是IntConsumer的实例,则将其强制转换为IntConsumer,
* 并传递给forEachRemaining(java.util.function.IntConsumer);
* 否则,通过将IntConsumer的参数装箱,操作将适应于IntConsumer的实例,
* 然后传递给forEachRemaining(java.util.function.IntConsumer)
*
*
*/
@Override
default void forEachRemaining(Consumer<? super Integer> action) {
if (action instanceof IntConsumer) {
forEachRemaining((IntConsumer) action);
}
else {
if (Tripwire.ENABLED)
Tripwire.trip(getClass(),
"{0} calling Spliterator.OfInt.forEachRemaining((IntConsumer) action::accept)");
forEachRemaining((IntConsumer) action::accept);
}
}
}
/**
* A Spliterator specialized for {@code long} values.
* 专用于long值的拆分器。
* @since 1.8
*/
public interface OfLong extends OfPrimitive<Long, LongConsumer, OfLong> {
@Override
OfLong trySplit();
@Override
boolean tryAdvance(LongConsumer action);
@Override
default void forEachRemaining(LongConsumer action) {
do { } while (tryAdvance(action));
}
/**
* {@inheritDoc}
* @implSpec
* If the action is an instance of {@code LongConsumer} then it is cast
* to {@code LongConsumer} and passed to
* {@link #tryAdvance(java.util.function.LongConsumer)}; otherwise
* the action is adapted to an instance of {@code LongConsumer}, by
* boxing the argument of {@code LongConsumer}, and then passed to
* {@link #tryAdvance(java.util.function.LongConsumer)}.
* 如果该操作是LongConsumer的实例,则将其强制转换为LongConsumer,
* 并传递给tryAdvance(java.util.function.LongConsumer);
* 否则,通过将LongConsumer的参数装箱,将操作改编为LongConsumer的实例,
* 然后将其传递给tryAdvance(java.util.function.LongConsumer)
*
*
*/
@Override
default boolean tryAdvance(Consumer<? super Long> action) {
if (action instanceof LongConsumer) {
return tryAdvance((LongConsumer) action);
}
else {
if (Tripwire.ENABLED)
Tripwire.trip(getClass(),
"{0} calling Spliterator.OfLong.tryAdvance((LongConsumer) action::accept)");
return tryAdvance((LongConsumer) action::accept);
}
}
/**
* {@inheritDoc}
* @implSpec
* If the action is an instance of {@code LongConsumer} then it is cast
* to {@code LongConsumer} and passed to
* {@link #forEachRemaining(java.util.function.LongConsumer)}; otherwise
* the action is adapted to an instance of {@code LongConsumer}, by
* boxing the argument of {@code LongConsumer}, and then passed to
* {@link #forEachRemaining(java.util.function.LongConsumer)}.
* 如果该操作是LongConsumer的实例,则将其强制转换为LongConsumer,
* 并传递给forEachRemaining(java.util.function.LongConsumer);
* 否则,通过将LongConsumer的参数装箱,将操作改编为LongConsumer的实例,
* 然后将其传递给forEachRemaining(java.util.function.LongConsumer)
*
*/
@Override
default void forEachRemaining(Consumer<? super Long> action) {
if (action instanceof LongConsumer) {
forEachRemaining((LongConsumer) action);
}
else {
if (Tripwire.ENABLED)
Tripwire.trip(getClass(),
"{0} calling Spliterator.OfLong.forEachRemaining((LongConsumer) action::accept)");
forEachRemaining((LongConsumer) action::accept);
}
}
}
/**
* A Spliterator specialized for {@code double} values.
* 专用于double值的拆分器。
* @since 1.8
*/
public interface OfDouble extends OfPrimitive<Double, DoubleConsumer, OfDouble> {
@Override
OfDouble trySplit();
@Override
boolean tryAdvance(DoubleConsumer action);
@Override
default void forEachRemaining(DoubleConsumer action) {
do { } while (tryAdvance(action));
}
/**
* {@inheritDoc}
* @implSpec
* If the action is an instance of {@code DoubleConsumer} then it is
* cast to {@code DoubleConsumer} and passed to
* {@link #tryAdvance(java.util.function.DoubleConsumer)}; otherwise
* the action is adapted to an instance of {@code DoubleConsumer}, by
* boxing the argument of {@code DoubleConsumer}, and then passed to
* {@link #tryAdvance(java.util.function.DoubleConsumer)}.
* 如果该操作是DoubleConsumer的实例,则将其强制转换为DoubleConsumer,
* 并传递给tryAdvance(java.util.function.DoubleConsumer);
* 否则,通过将DoubleConsumer的参数装箱,操作将适应于DoubleConsumer的实例,
* 然后传递给tryAdvance(java.util.function.DoubleConsumer)
*/
@Override
default boolean tryAdvance(Consumer<? super Double> action) {
if (action instanceof DoubleConsumer) {
return tryAdvance((DoubleConsumer) action);
}
else {
if (Tripwire.ENABLED)
Tripwire.trip(getClass(),
"{0} calling Spliterator.OfDouble.tryAdvance((DoubleConsumer) action::accept)");
return tryAdvance((DoubleConsumer) action::accept);
}
}
/**
* {@inheritDoc}
* @implSpec
* If the action is an instance of {@code DoubleConsumer} then it is
* cast to {@code DoubleConsumer} and passed to
* {@link #forEachRemaining(java.util.function.DoubleConsumer)};
* otherwise the action is adapted to an instance of
* {@code DoubleConsumer}, by boxing the argument of
* {@code DoubleConsumer}, and then passed to
* {@link #forEachRemaining(java.util.function.DoubleConsumer)}.
* 如果该操作是DoubleConsumer的实例,则将其强制转换为DoubleConsumer,
* 并传递给forEachRemaining(java.util.function.DoubleConsumer);
* 否则,通过将DoubleConsumer的参数装箱,操作将适应于DoubleConsumer的实例,
* 然后传递给forEachRemaining(java.util.function.DoubleConsumer)
*
*
*/
@Override
default void forEachRemaining(Consumer<? super Double> action) {
if (action instanceof DoubleConsumer) {
forEachRemaining((DoubleConsumer) action);
}
else {
if (Tripwire.ENABLED)
Tripwire.trip(getClass(),
"{0} calling Spliterator.OfDouble.forEachRemaining((DoubleConsumer) action::accept)");
forEachRemaining((DoubleConsumer) action::accept);
}
}
}
}