2020了你还不会Java8新特性?(七)Spliterator源码剖析

Spliterator javadoc

/**
 * 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.

 * 

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. Spliterator 可以对元素进行分区。 分成新的Spliterator。 并且以并行的操作来实行。 如果不能分割这些操作,则不能通过并行操作受益。 遍历和分割都会对那一小块是有用的、 *

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 这些特性可以在客户端使用,用来简化计算。是以位操作的形式来表示的。 collector中是以枚举形式来表示的。 * 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. 未来可能会定义一下新的特性。 实现者不应该赋予新的含义。 *

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. 当Spliterator 绑定到源上时 , 要考虑 IMMUTABLE 和 CONCURRENT 。 延迟迭代器会在第一次遍历或者分割或者查询大小的时候绑定在源上边。而不是在创建的时候就被绑定在源上了。 非延迟迭代器是在创建的时候就被绑定在源上了。 在迭代器绑定后对源进行了修改。迭代器就能反应出来抛出异常ConcurrentModificationException。 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 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. 如果 特性值 SIZED 。 那么将要遍历的数量是确定的。 如果不包含SIZED,一个估算的值对于源的操作也是有帮助的。 *

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. 分割迭代器并不确保是线程安全的。相反 应该确保分割迭代器一次被一个线程操作、 可以通过递归的方式来实现。 *

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. 为了避免重复的装箱和拆箱,我们应该使用巨化的方法。 减少使用通用的方法。 * * @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()}. 分割迭代器 就像迭代器一样。 用来遍历源当中的元素的。 Spliterator也支持并行的操作。方式是通过解耦,分解,单元素的遍历迭代。 Spliterator相比于Iterator来说,成本更低。tryAdvance()本质上也避免了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. 对于可变源来说,可能会出现问题 *

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}.
  • 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}.
  • 创建并发源、 特性值 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.
  • *
  • 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.
  • *
  • 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 action) {
 *       for (; origin < fence; origin += 2)
 *         action.accept((T) array[origin]);
 *     }
 *
        // 让这个迭代器往前走
 *     public boolean tryAdvance(Consumer action) {
 *       if (origin < fence) {
 *         action.accept((T) array[origin]);
 *         origin += 2;
 *         return true;
 *       }
 *       else // cannot advance
 *         return false;
 *     }
 *
        // 尝试进行分割, 尽量均匀的分割成两半. 不成功返回null
 *     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. * *

{@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. * 如果 {@code org.openjdk.java.util.stream.tripwire} 被设置成true, 则会给出警告。 * @param the type of elements returned by this Spliterator * * @see Collection * @since 1.8 */ public interface Spliterator { // 。。。 下方列举几个 }

tryAdvance();

/**
 * 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.
 *
 * @param action The action
 * @return {@code false} if no remaining elements existed
 * upon entry to this method, else {@code true}.
 * @throws NullPointerException if the specified action is null
 */
//尝试的去前进。如果有下一个元素,则进行动作。
boolean tryAdvance(Consumer action);  

forEachRemaining();

/**
 * 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.
 *
 * @implSpec
 * The default implementation repeatedly invokes {@link #tryAdvance} until
 * it returns {@code false}.  It should be overridden whenever possible.
 *
 * @param action The action
 * @throws NullPointerException if the specified action is null
 */
// 针对于剩余的元素进行操作。
default void forEachRemaining(Consumer action) {
    do { } while (tryAdvance(action));
}

trySplit();

/**
 * If this spliterator can be partitioned, returns a Spliterator
 * covering elements, that will, upon return from this method, not
 * be covered by this Spliterator.
 * 如果这个分割迭代器能被分割,则返回一个新的被分割出来的Spliterator对象。
 不会影响当前的spliterator
 * 

If this Spliterator is {@link #ORDERED}, the returned Spliterator * must cover a strict prefix of the elements. *如果Spliterator是有序的,则返回的也应该是有序的Spliterator *

Unless this Spliterator covers an infinite number of elements, * repeated calls to {@code trySplit()} must eventually return {@code null}. 除非Spliterator 返回的是无穷的元素,其余的最终返回一个null . 表示不能再继续分割了。 * Upon non-null return: 如果返回不为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.
  • 如果大小是固定的。则分割后的 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. * * @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. *理想情况下,是从中间分割的,允许并行计算。很多情况下不满足这种的、 然而没有效率的分割,会降低效率 * @return a {@code Spliterator} covering some portion of the * elements, or {@code null} if this spliterator cannot be split */ //尝试分割。 Spliterator trySplit();

estimateSize();

/**
 * 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.
 *
 * 

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}. * 分的越少,estimateSize要比原来的个数要小。 * @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. *一个不精算的数量也是有用的。 * @return the estimated size, or {@code Long.MAX_VALUE} if infinite, * unknown, or too expensive to compute. */ //估算大小 long estimateSize();

characteristics();

/**
 * 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.
 
 一个特性值的集合。
 重复的调用characteristics  在spliterator之前或者当中,会返回相同的结果。
 
 * 

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}. * * @return a representation of characteristics */ //特性值。 int characteristics();

hasCharacteristics();

/**
 * Returns {@code true} if this Spliterator's {@link
 * #characteristics} contain all of the given characteristics.
 *
 * @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}
 */
// 判断是否包含给定的特性值。  
default boolean hasCharacteristics(int characteristics) {
    return (characteristics() & characteristics) == characteristics;
}

getComparator();

/**
 * 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}.
 *
 * @implSpec
 * The default implementation always throws {@link IllegalStateException}.
 *
 * @return a Comparator, or {@code null} if the elements are sorted in the
 * natural order.
 * @throws IllegalStateException if the spliterator does not report
 *         a characteristic of {@code SORTED}.
 */
//有序的话 返回一个Null。 其他情况 抛异常
default Comparator getComparator() {
    throw new IllegalStateException();
}

IMMUTABLE

/**
 * 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.
 */
public static final int IMMUTABLE  = 0x00000400;   // 不能被修改的

CONCURRENT

/**
 * 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. * * @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;

OfPrimitive

/**
 * 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.
 * @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}.
 * @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}.
 *
 * @see Spliterator.OfInt
 * @see Spliterator.OfLong
 * @see Spliterator.OfDouble
 * @since 1.8
 */
public interface OfPrimitive>
        extends Spliterator {
    @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.
     *
     * @param action The action
     * @return {@code false} if no remaining elements existed
     * upon entry to this method, else {@code 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.
     *
     * @implSpec
     * The default implementation repeatedly invokes {@link #tryAdvance}
     * until it returns {@code false}.  It should be overridden whenever
     * possible.
     *
     * @param action The action
     * @throws NullPointerException if the specified action is null
     */
    @SuppressWarnings("overloads")
    default void forEachRemaining(T_CONS action) {
        do { } while (tryAdvance(action));
    }
}

OfInt

/**
 * A Spliterator specialized for {@code int} values.
 * @since 1.8
 */
public interface OfInt extends OfPrimitive {

    @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)}.
     */
    @Override
    default boolean tryAdvance(Consumer 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)}.
     */
    @Override
    default void forEachRemaining(Consumer 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);
        }
    }
}

IntConsumer 和 Consumer 是没有任何的关联关系 的。但是为什么能(IntConsumer)Consumer

因为jdk自带装箱拆箱操作。 int 和 integer 重叠了。

你可能感兴趣的:(2020了你还不会Java8新特性?(七)Spliterator源码剖析)