Home | History | Annotate | Download | only in util
      1 /*
      2  * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
      3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      4  *
      5  * This code is free software; you can redistribute it and/or modify it
      6  * under the terms of the GNU General Public License version 2 only, as
      7  * published by the Free Software Foundation.  Oracle designates this
      8  * particular file as subject to the "Classpath" exception as provided
      9  * by Oracle in the LICENSE file that accompanied this code.
     10  *
     11  * This code is distributed in the hope that it will be useful, but WITHOUT
     12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     14  * version 2 for more details (a copy is included in the LICENSE file that
     15  * accompanied this code).
     16  *
     17  * You should have received a copy of the GNU General Public License version
     18  * 2 along with this work; if not, write to the Free Software Foundation,
     19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     20  *
     21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     22  * or visit www.oracle.com if you need additional information or have any
     23  * questions.
     24  */
     25 package java.util;
     26 
     27 import java.util.function.Consumer;
     28 import java.util.function.DoubleConsumer;
     29 import java.util.function.IntConsumer;
     30 import java.util.function.LongConsumer;
     31 
     32 /**
     33  * Static classes and methods for operating on or creating instances of
     34  * {@link Spliterator} and its primitive specializations
     35  * {@link Spliterator.OfInt}, {@link Spliterator.OfLong}, and
     36  * {@link Spliterator.OfDouble}.
     37  *
     38  * @see Spliterator
     39  * @since 1.8
     40  */
     41 public final class Spliterators {
     42 
     43     // Suppresses default constructor, ensuring non-instantiability.
     44     private Spliterators() {}
     45 
     46     // Empty spliterators
     47 
     48     /**
     49      * Creates an empty {@code Spliterator}
     50      *
     51      * <p>The empty spliterator reports {@link Spliterator#SIZED} and
     52      * {@link Spliterator#SUBSIZED}.  Calls to
     53      * {@link java.util.Spliterator#trySplit()} always return {@code null}.
     54      *
     55      * @param <T> Type of elements
     56      * @return An empty spliterator
     57      */
     58     @SuppressWarnings("unchecked")
     59     public static <T> Spliterator<T> emptySpliterator() {
     60         return (Spliterator<T>) EMPTY_SPLITERATOR;
     61     }
     62 
     63     private static final Spliterator<Object> EMPTY_SPLITERATOR =
     64             new EmptySpliterator.OfRef<>();
     65 
     66     /**
     67      * Creates an empty {@code Spliterator.OfInt}
     68      *
     69      * <p>The empty spliterator reports {@link Spliterator#SIZED} and
     70      * {@link Spliterator#SUBSIZED}.  Calls to
     71      * {@link java.util.Spliterator#trySplit()} always return {@code null}.
     72      *
     73      * @return An empty spliterator
     74      */
     75     public static Spliterator.OfInt emptyIntSpliterator() {
     76         return EMPTY_INT_SPLITERATOR;
     77     }
     78 
     79     private static final Spliterator.OfInt EMPTY_INT_SPLITERATOR =
     80             new EmptySpliterator.OfInt();
     81 
     82     /**
     83      * Creates an empty {@code Spliterator.OfLong}
     84      *
     85      * <p>The empty spliterator reports {@link Spliterator#SIZED} and
     86      * {@link Spliterator#SUBSIZED}.  Calls to
     87      * {@link java.util.Spliterator#trySplit()} always return {@code null}.
     88      *
     89      * @return An empty spliterator
     90      */
     91     public static Spliterator.OfLong emptyLongSpliterator() {
     92         return EMPTY_LONG_SPLITERATOR;
     93     }
     94 
     95     private static final Spliterator.OfLong EMPTY_LONG_SPLITERATOR =
     96             new EmptySpliterator.OfLong();
     97 
     98     /**
     99      * Creates an empty {@code Spliterator.OfDouble}
    100      *
    101      * <p>The empty spliterator reports {@link Spliterator#SIZED} and
    102      * {@link Spliterator#SUBSIZED}.  Calls to
    103      * {@link java.util.Spliterator#trySplit()} always return {@code null}.
    104      *
    105      * @return An empty spliterator
    106      */
    107     public static Spliterator.OfDouble emptyDoubleSpliterator() {
    108         return EMPTY_DOUBLE_SPLITERATOR;
    109     }
    110 
    111     private static final Spliterator.OfDouble EMPTY_DOUBLE_SPLITERATOR =
    112             new EmptySpliterator.OfDouble();
    113 
    114     // Array-based spliterators
    115 
    116     /**
    117      * Creates a {@code Spliterator} covering the elements of a given array,
    118      * using a customized set of spliterator characteristics.
    119      *
    120      * <p>This method is provided as an implementation convenience for
    121      * Spliterators which store portions of their elements in arrays, and need
    122      * fine control over Spliterator characteristics.  Most other situations in
    123      * which a Spliterator for an array is needed should use
    124      * {@link Arrays#spliterator(Object[])}.
    125      *
    126      * <p>The returned spliterator always reports the characteristics
    127      * {@code SIZED} and {@code SUBSIZED}.  The caller may provide additional
    128      * characteristics for the spliterator to report; it is common to
    129      * additionally specify {@code IMMUTABLE} and {@code ORDERED}.
    130      *
    131      * @param <T> Type of elements
    132      * @param array The array, assumed to be unmodified during use
    133      * @param additionalCharacteristics Additional spliterator characteristics
    134      *        of this spliterator's source or elements beyond {@code SIZED} and
    135      *        {@code SUBSIZED} which are are always reported
    136      * @return A spliterator for an array
    137      * @throws NullPointerException if the given array is {@code null}
    138      * @see Arrays#spliterator(Object[])
    139      */
    140     public static <T> Spliterator<T> spliterator(Object[] array,
    141                                                  int additionalCharacteristics) {
    142         return new ArraySpliterator<>(Objects.requireNonNull(array),
    143                                       additionalCharacteristics);
    144     }
    145 
    146     /**
    147      * Creates a {@code Spliterator} covering a range of elements of a given
    148      * array, using a customized set of spliterator characteristics.
    149      *
    150      * <p>This method is provided as an implementation convenience for
    151      * Spliterators which store portions of their elements in arrays, and need
    152      * fine control over Spliterator characteristics.  Most other situations in
    153      * which a Spliterator for an array is needed should use
    154      * {@link Arrays#spliterator(Object[])}.
    155      *
    156      * <p>The returned spliterator always reports the characteristics
    157      * {@code SIZED} and {@code SUBSIZED}.  The caller may provide additional
    158      * characteristics for the spliterator to report; it is common to
    159      * additionally specify {@code IMMUTABLE} and {@code ORDERED}.
    160      *
    161      * @param <T> Type of elements
    162      * @param array The array, assumed to be unmodified during use
    163      * @param fromIndex The least index (inclusive) to cover
    164      * @param toIndex One past the greatest index to cover
    165      * @param additionalCharacteristics Additional spliterator characteristics
    166      *        of this spliterator's source or elements beyond {@code SIZED} and
    167      *        {@code SUBSIZED} which are are always reported
    168      * @return A spliterator for an array
    169      * @throws NullPointerException if the given array is {@code null}
    170      * @throws ArrayIndexOutOfBoundsException if {@code fromIndex} is negative,
    171      *         {@code toIndex} is less than {@code fromIndex}, or
    172      *         {@code toIndex} is greater than the array size
    173      * @see Arrays#spliterator(Object[], int, int)
    174      */
    175     public static <T> Spliterator<T> spliterator(Object[] array, int fromIndex, int toIndex,
    176                                                  int additionalCharacteristics) {
    177         checkFromToBounds(Objects.requireNonNull(array).length, fromIndex, toIndex);
    178         return new ArraySpliterator<>(array, fromIndex, toIndex, additionalCharacteristics);
    179     }
    180 
    181     /**
    182      * Creates a {@code Spliterator.OfInt} covering the elements of a given array,
    183      * using a customized set of spliterator characteristics.
    184      *
    185      * <p>This method is provided as an implementation convenience for
    186      * Spliterators which store portions of their elements in arrays, and need
    187      * fine control over Spliterator characteristics.  Most other situations in
    188      * which a Spliterator for an array is needed should use
    189      * {@link Arrays#spliterator(int[])}.
    190      *
    191      * <p>The returned spliterator always reports the characteristics
    192      * {@code SIZED} and {@code SUBSIZED}.  The caller may provide additional
    193      * characteristics for the spliterator to report; it is common to
    194      * additionally specify {@code IMMUTABLE} and {@code ORDERED}.
    195      *
    196      * @param array The array, assumed to be unmodified during use
    197      * @param additionalCharacteristics Additional spliterator characteristics
    198      *        of this spliterator's source or elements beyond {@code SIZED} and
    199      *        {@code SUBSIZED} which are are always reported
    200      * @return A spliterator for an array
    201      * @throws NullPointerException if the given array is {@code null}
    202      * @see Arrays#spliterator(int[])
    203      */
    204     public static Spliterator.OfInt spliterator(int[] array,
    205                                                 int additionalCharacteristics) {
    206         return new IntArraySpliterator(Objects.requireNonNull(array), additionalCharacteristics);
    207     }
    208 
    209     /**
    210      * Creates a {@code Spliterator.OfInt} covering a range of elements of a
    211      * given array, using a customized set of spliterator characteristics.
    212      *
    213      * <p>This method is provided as an implementation convenience for
    214      * Spliterators which store portions of their elements in arrays, and need
    215      * fine control over Spliterator characteristics.  Most other situations in
    216      * which a Spliterator for an array is needed should use
    217      * {@link Arrays#spliterator(int[], int, int)}.
    218      *
    219      * <p>The returned spliterator always reports the characteristics
    220      * {@code SIZED} and {@code SUBSIZED}.  The caller may provide additional
    221      * characteristics for the spliterator to report; it is common to
    222      * additionally specify {@code IMMUTABLE} and {@code ORDERED}.
    223      *
    224      * @param array The array, assumed to be unmodified during use
    225      * @param fromIndex The least index (inclusive) to cover
    226      * @param toIndex One past the greatest index to cover
    227      * @param additionalCharacteristics Additional spliterator characteristics
    228      *        of this spliterator's source or elements beyond {@code SIZED} and
    229      *        {@code SUBSIZED} which are are always reported
    230      * @return A spliterator for an array
    231      * @throws NullPointerException if the given array is {@code null}
    232      * @throws ArrayIndexOutOfBoundsException if {@code fromIndex} is negative,
    233      *         {@code toIndex} is less than {@code fromIndex}, or
    234      *         {@code toIndex} is greater than the array size
    235      * @see Arrays#spliterator(int[], int, int)
    236      */
    237     public static Spliterator.OfInt spliterator(int[] array, int fromIndex, int toIndex,
    238                                                 int additionalCharacteristics) {
    239         checkFromToBounds(Objects.requireNonNull(array).length, fromIndex, toIndex);
    240         return new IntArraySpliterator(array, fromIndex, toIndex, additionalCharacteristics);
    241     }
    242 
    243     /**
    244      * Creates a {@code Spliterator.OfLong} covering the elements of a given array,
    245      * using a customized set of spliterator characteristics.
    246      *
    247      * <p>This method is provided as an implementation convenience for
    248      * Spliterators which store portions of their elements in arrays, and need
    249      * fine control over Spliterator characteristics.  Most other situations in
    250      * which a Spliterator for an array is needed should use
    251      * {@link Arrays#spliterator(long[])}.
    252      *
    253      * <p>The returned spliterator always reports the characteristics
    254      * {@code SIZED} and {@code SUBSIZED}.  The caller may provide additional
    255      * characteristics for the spliterator to report; it is common to
    256      * additionally specify {@code IMMUTABLE} and {@code ORDERED}.
    257      *
    258      * @param array The array, assumed to be unmodified during use
    259      * @param additionalCharacteristics Additional spliterator characteristics
    260      *        of this spliterator's source or elements beyond {@code SIZED} and
    261      *        {@code SUBSIZED} which are are always reported
    262      * @return A spliterator for an array
    263      * @throws NullPointerException if the given array is {@code null}
    264      * @see Arrays#spliterator(long[])
    265      */
    266     public static Spliterator.OfLong spliterator(long[] array,
    267                                                  int additionalCharacteristics) {
    268         return new LongArraySpliterator(Objects.requireNonNull(array), additionalCharacteristics);
    269     }
    270 
    271     /**
    272      * Creates a {@code Spliterator.OfLong} covering a range of elements of a
    273      * given array, using a customized set of spliterator characteristics.
    274      *
    275      * <p>This method is provided as an implementation convenience for
    276      * Spliterators which store portions of their elements in arrays, and need
    277      * fine control over Spliterator characteristics.  Most other situations in
    278      * which a Spliterator for an array is needed should use
    279      * {@link Arrays#spliterator(long[], int, int)}.
    280      *
    281      * <p>The returned spliterator always reports the characteristics
    282      * {@code SIZED} and {@code SUBSIZED}.  The caller may provide additional
    283      * characteristics for the spliterator to report.  (For example, if it is
    284      * known the array will not be further modified, specify {@code IMMUTABLE};
    285      * if the array data is considered to have an an encounter order, specify
    286      * {@code ORDERED}).  The method {@link Arrays#spliterator(long[], int, int)} can
    287      * often be used instead, which returns a spliterator that reports
    288      * {@code SIZED}, {@code SUBSIZED}, {@code IMMUTABLE}, and {@code ORDERED}.
    289      *
    290      * @param array The array, assumed to be unmodified during use
    291      * @param fromIndex The least index (inclusive) to cover
    292      * @param toIndex One past the greatest index to cover
    293      * @param additionalCharacteristics Additional spliterator characteristics
    294      *        of this spliterator's source or elements beyond {@code SIZED} and
    295      *        {@code SUBSIZED} which are are always reported
    296      * @return A spliterator for an array
    297      * @throws NullPointerException if the given array is {@code null}
    298      * @throws ArrayIndexOutOfBoundsException if {@code fromIndex} is negative,
    299      *         {@code toIndex} is less than {@code fromIndex}, or
    300      *         {@code toIndex} is greater than the array size
    301      * @see Arrays#spliterator(long[], int, int)
    302      */
    303     public static Spliterator.OfLong spliterator(long[] array, int fromIndex, int toIndex,
    304                                                  int additionalCharacteristics) {
    305         checkFromToBounds(Objects.requireNonNull(array).length, fromIndex, toIndex);
    306         return new LongArraySpliterator(array, fromIndex, toIndex, additionalCharacteristics);
    307     }
    308 
    309     /**
    310      * Creates a {@code Spliterator.OfDouble} covering the elements of a given array,
    311      * using a customized set of spliterator characteristics.
    312      *
    313      * <p>This method is provided as an implementation convenience for
    314      * Spliterators which store portions of their elements in arrays, and need
    315      * fine control over Spliterator characteristics.  Most other situations in
    316      * which a Spliterator for an array is needed should use
    317      * {@link Arrays#spliterator(double[])}.
    318      *
    319      * <p>The returned spliterator always reports the characteristics
    320      * {@code SIZED} and {@code SUBSIZED}.  The caller may provide additional
    321      * characteristics for the spliterator to report; it is common to
    322      * additionally specify {@code IMMUTABLE} and {@code ORDERED}.
    323      *
    324      * @param array The array, assumed to be unmodified during use
    325      * @param additionalCharacteristics Additional spliterator characteristics
    326      *        of this spliterator's source or elements beyond {@code SIZED} and
    327      *        {@code SUBSIZED} which are are always reported
    328      * @return A spliterator for an array
    329      * @throws NullPointerException if the given array is {@code null}
    330      * @see Arrays#spliterator(double[])
    331      */
    332     public static Spliterator.OfDouble spliterator(double[] array,
    333                                                    int additionalCharacteristics) {
    334         return new DoubleArraySpliterator(Objects.requireNonNull(array), additionalCharacteristics);
    335     }
    336 
    337     /**
    338      * Creates a {@code Spliterator.OfDouble} covering a range of elements of a
    339      * given array, using a customized set of spliterator characteristics.
    340      *
    341      * <p>This method is provided as an implementation convenience for
    342      * Spliterators which store portions of their elements in arrays, and need
    343      * fine control over Spliterator characteristics.  Most other situations in
    344      * which a Spliterator for an array is needed should use
    345      * {@link Arrays#spliterator(double[], int, int)}.
    346      *
    347      * <p>The returned spliterator always reports the characteristics
    348      * {@code SIZED} and {@code SUBSIZED}.  The caller may provide additional
    349      * characteristics for the spliterator to report.  (For example, if it is
    350      * known the array will not be further modified, specify {@code IMMUTABLE};
    351      * if the array data is considered to have an an encounter order, specify
    352      * {@code ORDERED}).  The method {@link Arrays#spliterator(long[], int, int)} can
    353      * often be used instead, which returns a spliterator that reports
    354      * {@code SIZED}, {@code SUBSIZED}, {@code IMMUTABLE}, and {@code ORDERED}.
    355      *
    356      * @param array The array, assumed to be unmodified during use
    357      * @param fromIndex The least index (inclusive) to cover
    358      * @param toIndex One past the greatest index to cover
    359      * @param additionalCharacteristics Additional spliterator characteristics
    360      *        of this spliterator's source or elements beyond {@code SIZED} and
    361      *        {@code SUBSIZED} which are are always reported
    362      * @return A spliterator for an array
    363      * @throws NullPointerException if the given array is {@code null}
    364      * @throws ArrayIndexOutOfBoundsException if {@code fromIndex} is negative,
    365      *         {@code toIndex} is less than {@code fromIndex}, or
    366      *         {@code toIndex} is greater than the array size
    367      * @see Arrays#spliterator(double[], int, int)
    368      */
    369     public static Spliterator.OfDouble spliterator(double[] array, int fromIndex, int toIndex,
    370                                                    int additionalCharacteristics) {
    371         checkFromToBounds(Objects.requireNonNull(array).length, fromIndex, toIndex);
    372         return new DoubleArraySpliterator(array, fromIndex, toIndex, additionalCharacteristics);
    373     }
    374 
    375     /**
    376      * Validate inclusive start index and exclusive end index against the length
    377      * of an array.
    378      * @param arrayLength The length of the array
    379      * @param origin The inclusive start index
    380      * @param fence The exclusive end index
    381      * @throws ArrayIndexOutOfBoundsException if the start index is greater than
    382      * the end index, if the start index is negative, or the end index is
    383      * greater than the array length
    384      */
    385     private static void checkFromToBounds(int arrayLength, int origin, int fence) {
    386         if (origin > fence) {
    387             throw new ArrayIndexOutOfBoundsException(
    388                     "origin(" + origin + ") > fence(" + fence + ")");
    389         }
    390         if (origin < 0) {
    391             throw new ArrayIndexOutOfBoundsException(origin);
    392         }
    393         if (fence > arrayLength) {
    394             throw new ArrayIndexOutOfBoundsException(fence);
    395         }
    396     }
    397 
    398     // Iterator-based spliterators
    399 
    400     /**
    401      * Creates a {@code Spliterator} using the given collection's
    402      * {@link java.util.Collection#iterator()} as the source of elements, and
    403      * reporting its {@link java.util.Collection#size()} as its initial size.
    404      *
    405      * <p>The spliterator is
    406      * <em><a href="Spliterator.html#binding">late-binding</a></em>, inherits
    407      * the <em>fail-fast</em> properties of the collection's iterator, and
    408      * implements {@code trySplit} to permit limited parallelism.
    409      *
    410      * @param <T> Type of elements
    411      * @param c The collection
    412      * @param characteristics Characteristics of this spliterator's source or
    413      *        elements.  The characteristics {@code SIZED} and {@code SUBSIZED}
    414      *        are additionally reported unless {@code CONCURRENT} is supplied.
    415      * @return A spliterator from an iterator
    416      * @throws NullPointerException if the given collection is {@code null}
    417      */
    418     public static <T> Spliterator<T> spliterator(Collection<? extends T> c,
    419                                                  int characteristics) {
    420         return new IteratorSpliterator<>(Objects.requireNonNull(c),
    421                                          characteristics);
    422     }
    423 
    424     /**
    425      * Creates a {@code Spliterator} using a given {@code Iterator}
    426      * as the source of elements, and with a given initially reported size.
    427      *
    428      * <p>The spliterator is not
    429      * <em><a href="Spliterator.html#binding">late-binding</a></em>, inherits
    430      * the <em>fail-fast</em> properties of the iterator, and implements
    431      * {@code trySplit} to permit limited parallelism.
    432      *
    433      * <p>Traversal of elements should be accomplished through the spliterator.
    434      * The behaviour of splitting and traversal is undefined if the iterator is
    435      * operated on after the spliterator is returned, or the initially reported
    436      * size is not equal to the actual number of elements in the source.
    437      *
    438      * @param <T> Type of elements
    439      * @param iterator The iterator for the source
    440      * @param size The number of elements in the source, to be reported as
    441      *        initial {@code estimateSize}
    442      * @param characteristics Characteristics of this spliterator's source or
    443      *        elements.  The characteristics {@code SIZED} and {@code SUBSIZED}
    444      *        are additionally reported unless {@code CONCURRENT} is supplied.
    445      * @return A spliterator from an iterator
    446      * @throws NullPointerException if the given iterator is {@code null}
    447      */
    448     public static <T> Spliterator<T> spliterator(Iterator<? extends T> iterator,
    449                                                  long size,
    450                                                  int characteristics) {
    451         return new IteratorSpliterator<>(Objects.requireNonNull(iterator), size,
    452                                          characteristics);
    453     }
    454 
    455     /**
    456      * Creates a {@code Spliterator} using a given {@code Iterator}
    457      * as the source of elements, with no initial size estimate.
    458      *
    459      * <p>The spliterator is not
    460      * <em><a href="Spliterator.html#binding">late-binding</a></em>, inherits
    461      * the <em>fail-fast</em> properties of the iterator, and implements
    462      * {@code trySplit} to permit limited parallelism.
    463      *
    464      * <p>Traversal of elements should be accomplished through the spliterator.
    465      * The behaviour of splitting and traversal is undefined if the iterator is
    466      * operated on after the spliterator is returned.
    467      *
    468      * @param <T> Type of elements
    469      * @param iterator The iterator for the source
    470      * @param characteristics Characteristics of this spliterator's source
    471      *        or elements ({@code SIZED} and {@code SUBSIZED}, if supplied, are
    472      *        ignored and are not reported.)
    473      * @return A spliterator from an iterator
    474      * @throws NullPointerException if the given iterator is {@code null}
    475      */
    476     public static <T> Spliterator<T> spliteratorUnknownSize(Iterator<? extends T> iterator,
    477                                                             int characteristics) {
    478         return new IteratorSpliterator<>(Objects.requireNonNull(iterator), characteristics);
    479     }
    480 
    481     /**
    482      * Creates a {@code Spliterator.OfInt} using a given
    483      * {@code IntStream.IntIterator} as the source of elements, and with a given
    484      * initially reported size.
    485      *
    486      * <p>The spliterator is not
    487      * <em><a href="Spliterator.html#binding">late-binding</a></em>, inherits
    488      * the <em>fail-fast</em> properties of the iterator, and implements
    489      * {@code trySplit} to permit limited parallelism.
    490      *
    491      * <p>Traversal of elements should be accomplished through the spliterator.
    492      * The behaviour of splitting and traversal is undefined if the iterator is
    493      * operated on after the spliterator is returned, or the initially reported
    494      * size is not equal to the actual number of elements in the source.
    495      *
    496      * @param iterator The iterator for the source
    497      * @param size The number of elements in the source, to be reported as
    498      *        initial {@code estimateSize}.
    499      * @param characteristics Characteristics of this spliterator's source or
    500      *        elements.  The characteristics {@code SIZED} and {@code SUBSIZED}
    501      *        are additionally reported unless {@code CONCURRENT} is supplied.
    502      * @return A spliterator from an iterator
    503      * @throws NullPointerException if the given iterator is {@code null}
    504      */
    505     public static Spliterator.OfInt spliterator(PrimitiveIterator.OfInt iterator,
    506                                                 long size,
    507                                                 int characteristics) {
    508         return new IntIteratorSpliterator(Objects.requireNonNull(iterator),
    509                                           size, characteristics);
    510     }
    511 
    512     /**
    513      * Creates a {@code Spliterator.OfInt} using a given
    514      * {@code IntStream.IntIterator} as the source of elements, with no initial
    515      * size estimate.
    516      *
    517      * <p>The spliterator is not
    518      * <em><a href="Spliterator.html#binding">late-binding</a></em>, inherits
    519      * the <em>fail-fast</em> properties of the iterator, and implements
    520      * {@code trySplit} to permit limited parallelism.
    521      *
    522      * <p>Traversal of elements should be accomplished through the spliterator.
    523      * The behaviour of splitting and traversal is undefined if the iterator is
    524      * operated on after the spliterator is returned.
    525      *
    526      * @param iterator The iterator for the source
    527      * @param characteristics Characteristics of this spliterator's source
    528      *        or elements ({@code SIZED} and {@code SUBSIZED}, if supplied, are
    529      *        ignored and are not reported.)
    530      * @return A spliterator from an iterator
    531      * @throws NullPointerException if the given iterator is {@code null}
    532      */
    533     public static Spliterator.OfInt spliteratorUnknownSize(PrimitiveIterator.OfInt iterator,
    534                                                            int characteristics) {
    535         return new IntIteratorSpliterator(Objects.requireNonNull(iterator), characteristics);
    536     }
    537 
    538     /**
    539      * Creates a {@code Spliterator.OfLong} using a given
    540      * {@code LongStream.LongIterator} as the source of elements, and with a
    541      * given initially reported size.
    542      *
    543      * <p>The spliterator is not
    544      * <em><a href="Spliterator.html#binding">late-binding</a></em>, inherits
    545      * the <em>fail-fast</em> properties of the iterator, and implements
    546      * {@code trySplit} to permit limited parallelism.
    547      *
    548      * <p>Traversal of elements should be accomplished through the spliterator.
    549      * The behaviour of splitting and traversal is undefined if the iterator is
    550      * operated on after the spliterator is returned, or the initially reported
    551      * size is not equal to the actual number of elements in the source.
    552      *
    553      * @param iterator The iterator for the source
    554      * @param size The number of elements in the source, to be reported as
    555      *        initial {@code estimateSize}.
    556      * @param characteristics Characteristics of this spliterator's source or
    557      *        elements.  The characteristics {@code SIZED} and {@code SUBSIZED}
    558      *        are additionally reported unless {@code CONCURRENT} is supplied.
    559      * @return A spliterator from an iterator
    560      * @throws NullPointerException if the given iterator is {@code null}
    561      */
    562     public static Spliterator.OfLong spliterator(PrimitiveIterator.OfLong iterator,
    563                                                  long size,
    564                                                  int characteristics) {
    565         return new LongIteratorSpliterator(Objects.requireNonNull(iterator),
    566                                            size, characteristics);
    567     }
    568 
    569     /**
    570      * Creates a {@code Spliterator.OfLong} using a given
    571      * {@code LongStream.LongIterator} as the source of elements, with no
    572      * initial size estimate.
    573      *
    574      * <p>The spliterator is not
    575      * <em><a href="Spliterator.html#binding">late-binding</a></em>, inherits
    576      * the <em>fail-fast</em> properties of the iterator, and implements
    577      * {@code trySplit} to permit limited parallelism.
    578      *
    579      * <p>Traversal of elements should be accomplished through the spliterator.
    580      * The behaviour of splitting and traversal is undefined if the iterator is
    581      * operated on after the spliterator is returned.
    582      *
    583      * @param iterator The iterator for the source
    584      * @param characteristics Characteristics of this spliterator's source
    585      *        or elements ({@code SIZED} and {@code SUBSIZED}, if supplied, are
    586      *        ignored and are not reported.)
    587      * @return A spliterator from an iterator
    588      * @throws NullPointerException if the given iterator is {@code null}
    589      */
    590     public static Spliterator.OfLong spliteratorUnknownSize(PrimitiveIterator.OfLong iterator,
    591                                                             int characteristics) {
    592         return new LongIteratorSpliterator(Objects.requireNonNull(iterator), characteristics);
    593     }
    594 
    595     /**
    596      * Creates a {@code Spliterator.OfDouble} using a given
    597      * {@code DoubleStream.DoubleIterator} as the source of elements, and with a
    598      * given initially reported size.
    599      *
    600      * <p>The spliterator is not
    601      * <em><a href="Spliterator.html#binding">late-binding</a></em>, inherits
    602      * the <em>fail-fast</em> properties of the iterator, and implements
    603      * {@code trySplit} to permit limited parallelism.
    604      *
    605      * <p>Traversal of elements should be accomplished through the spliterator.
    606      * The behaviour of splitting and traversal is undefined if the iterator is
    607      * operated on after the spliterator is returned, or the initially reported
    608      * size is not equal to the actual number of elements in the source.
    609      *
    610      * @param iterator The iterator for the source
    611      * @param size The number of elements in the source, to be reported as
    612      *        initial {@code estimateSize}
    613      * @param characteristics Characteristics of this spliterator's source or
    614      *        elements.  The characteristics {@code SIZED} and {@code SUBSIZED}
    615      *        are additionally reported unless {@code CONCURRENT} is supplied.
    616      * @return A spliterator from an iterator
    617      * @throws NullPointerException if the given iterator is {@code null}
    618      */
    619     public static Spliterator.OfDouble spliterator(PrimitiveIterator.OfDouble iterator,
    620                                                    long size,
    621                                                    int characteristics) {
    622         return new DoubleIteratorSpliterator(Objects.requireNonNull(iterator),
    623                                              size, characteristics);
    624     }
    625 
    626     /**
    627      * Creates a {@code Spliterator.OfDouble} using a given
    628      * {@code DoubleStream.DoubleIterator} as the source of elements, with no
    629      * initial size estimate.
    630      *
    631      * <p>The spliterator is not
    632      * <em><a href="Spliterator.html#binding">late-binding</a></em>, inherits
    633      * the <em>fail-fast</em> properties of the iterator, and implements
    634      * {@code trySplit} to permit limited parallelism.
    635      *
    636      * <p>Traversal of elements should be accomplished through the spliterator.
    637      * The behaviour of splitting and traversal is undefined if the iterator is
    638      * operated on after the spliterator is returned.
    639      *
    640      * @param iterator The iterator for the source
    641      * @param characteristics Characteristics of this spliterator's source
    642      *        or elements ({@code SIZED} and {@code SUBSIZED}, if supplied, are
    643      *        ignored and are not reported.)
    644      * @return A spliterator from an iterator
    645      * @throws NullPointerException if the given iterator is {@code null}
    646      */
    647     public static Spliterator.OfDouble spliteratorUnknownSize(PrimitiveIterator.OfDouble iterator,
    648                                                               int characteristics) {
    649         return new DoubleIteratorSpliterator(Objects.requireNonNull(iterator), characteristics);
    650     }
    651 
    652     // Iterators from Spliterators
    653 
    654     /**
    655      * Creates an {@code Iterator} from a {@code Spliterator}.
    656      *
    657      * <p>Traversal of elements should be accomplished through the iterator.
    658      * The behaviour of traversal is undefined if the spliterator is operated
    659      * after the iterator is returned.
    660      *
    661      * @param <T> Type of elements
    662      * @param spliterator The spliterator
    663      * @return An iterator
    664      * @throws NullPointerException if the given spliterator is {@code null}
    665      */
    666     public static<T> Iterator<T> iterator(Spliterator<? extends T> spliterator) {
    667         Objects.requireNonNull(spliterator);
    668         class Adapter implements Iterator<T>, Consumer<T> {
    669             boolean valueReady = false;
    670             T nextElement;
    671 
    672             @Override
    673             public void accept(T t) {
    674                 valueReady = true;
    675                 nextElement = t;
    676             }
    677 
    678             @Override
    679             public boolean hasNext() {
    680                 if (!valueReady)
    681                     spliterator.tryAdvance(this);
    682                 return valueReady;
    683             }
    684 
    685             @Override
    686             public T next() {
    687                 if (!valueReady && !hasNext())
    688                     throw new NoSuchElementException();
    689                 else {
    690                     valueReady = false;
    691                     return nextElement;
    692                 }
    693             }
    694         }
    695 
    696         return new Adapter();
    697     }
    698 
    699     /**
    700      * Creates an {@code PrimitiveIterator.OfInt} from a
    701      * {@code Spliterator.OfInt}.
    702      *
    703      * <p>Traversal of elements should be accomplished through the iterator.
    704      * The behaviour of traversal is undefined if the spliterator is operated
    705      * after the iterator is returned.
    706      *
    707      * @param spliterator The spliterator
    708      * @return An iterator
    709      * @throws NullPointerException if the given spliterator is {@code null}
    710      */
    711     public static PrimitiveIterator.OfInt iterator(Spliterator.OfInt spliterator) {
    712         Objects.requireNonNull(spliterator);
    713         class Adapter implements PrimitiveIterator.OfInt, IntConsumer {
    714             boolean valueReady = false;
    715             int nextElement;
    716 
    717             @Override
    718             public void accept(int t) {
    719                 valueReady = true;
    720                 nextElement = t;
    721             }
    722 
    723             @Override
    724             public boolean hasNext() {
    725                 if (!valueReady)
    726                     spliterator.tryAdvance(this);
    727                 return valueReady;
    728             }
    729 
    730             @Override
    731             public int nextInt() {
    732                 if (!valueReady && !hasNext())
    733                     throw new NoSuchElementException();
    734                 else {
    735                     valueReady = false;
    736                     return nextElement;
    737                 }
    738             }
    739         }
    740 
    741         return new Adapter();
    742     }
    743 
    744     /**
    745      * Creates an {@code PrimitiveIterator.OfLong} from a
    746      * {@code Spliterator.OfLong}.
    747      *
    748      * <p>Traversal of elements should be accomplished through the iterator.
    749      * The behaviour of traversal is undefined if the spliterator is operated
    750      * after the iterator is returned.
    751      *
    752      * @param spliterator The spliterator
    753      * @return An iterator
    754      * @throws NullPointerException if the given spliterator is {@code null}
    755      */
    756     public static PrimitiveIterator.OfLong iterator(Spliterator.OfLong spliterator) {
    757         Objects.requireNonNull(spliterator);
    758         class Adapter implements PrimitiveIterator.OfLong, LongConsumer {
    759             boolean valueReady = false;
    760             long nextElement;
    761 
    762             @Override
    763             public void accept(long t) {
    764                 valueReady = true;
    765                 nextElement = t;
    766             }
    767 
    768             @Override
    769             public boolean hasNext() {
    770                 if (!valueReady)
    771                     spliterator.tryAdvance(this);
    772                 return valueReady;
    773             }
    774 
    775             @Override
    776             public long nextLong() {
    777                 if (!valueReady && !hasNext())
    778                     throw new NoSuchElementException();
    779                 else {
    780                     valueReady = false;
    781                     return nextElement;
    782                 }
    783             }
    784         }
    785 
    786         return new Adapter();
    787     }
    788 
    789     /**
    790      * Creates an {@code PrimitiveIterator.OfDouble} from a
    791      * {@code Spliterator.OfDouble}.
    792      *
    793      * <p>Traversal of elements should be accomplished through the iterator.
    794      * The behaviour of traversal is undefined if the spliterator is operated
    795      * after the iterator is returned.
    796      *
    797      * @param spliterator The spliterator
    798      * @return An iterator
    799      * @throws NullPointerException if the given spliterator is {@code null}
    800      */
    801     public static PrimitiveIterator.OfDouble iterator(Spliterator.OfDouble spliterator) {
    802         Objects.requireNonNull(spliterator);
    803         class Adapter implements PrimitiveIterator.OfDouble, DoubleConsumer {
    804             boolean valueReady = false;
    805             double nextElement;
    806 
    807             @Override
    808             public void accept(double t) {
    809                 valueReady = true;
    810                 nextElement = t;
    811             }
    812 
    813             @Override
    814             public boolean hasNext() {
    815                 if (!valueReady)
    816                     spliterator.tryAdvance(this);
    817                 return valueReady;
    818             }
    819 
    820             @Override
    821             public double nextDouble() {
    822                 if (!valueReady && !hasNext())
    823                     throw new NoSuchElementException();
    824                 else {
    825                     valueReady = false;
    826                     return nextElement;
    827                 }
    828             }
    829         }
    830 
    831         return new Adapter();
    832     }
    833 
    834     // Implementations
    835 
    836     private static abstract class EmptySpliterator<T, S extends Spliterator<T>, C> {
    837 
    838         EmptySpliterator() { }
    839 
    840         public S trySplit() {
    841             return null;
    842         }
    843 
    844         public boolean tryAdvance(C consumer) {
    845             Objects.requireNonNull(consumer);
    846             return false;
    847         }
    848 
    849         public void forEachRemaining(C consumer) {
    850             Objects.requireNonNull(consumer);
    851         }
    852 
    853         public long estimateSize() {
    854             return 0;
    855         }
    856 
    857         public int characteristics() {
    858             return Spliterator.SIZED | Spliterator.SUBSIZED;
    859         }
    860 
    861         private static final class OfRef<T>
    862                 extends EmptySpliterator<T, Spliterator<T>, Consumer<? super T>>
    863                 implements Spliterator<T> {
    864             OfRef() { }
    865         }
    866 
    867         private static final class OfInt
    868                 extends EmptySpliterator<Integer, Spliterator.OfInt, IntConsumer>
    869                 implements Spliterator.OfInt {
    870             OfInt() { }
    871         }
    872 
    873         private static final class OfLong
    874                 extends EmptySpliterator<Long, Spliterator.OfLong, LongConsumer>
    875                 implements Spliterator.OfLong {
    876             OfLong() { }
    877         }
    878 
    879         private static final class OfDouble
    880                 extends EmptySpliterator<Double, Spliterator.OfDouble, DoubleConsumer>
    881                 implements Spliterator.OfDouble {
    882             OfDouble() { }
    883         }
    884     }
    885 
    886     // Array-based spliterators
    887 
    888     /**
    889      * A Spliterator designed for use by sources that traverse and split
    890      * elements maintained in an unmodifiable {@code Object[]} array.
    891      */
    892     static final class ArraySpliterator<T> implements Spliterator<T> {
    893         /**
    894          * The array, explicitly typed as Object[]. Unlike in some other
    895          * classes (see for example CR 6260652), we do not need to
    896          * screen arguments to ensure they are exactly of type Object[]
    897          * so long as no methods write into the array or serialize it,
    898          * which we ensure here by defining this class as final.
    899          */
    900         private final Object[] array;
    901         private int index;        // current index, modified on advance/split
    902         private final int fence;  // one past last index
    903         private final int characteristics;
    904 
    905         /**
    906          * Creates a spliterator covering all of the given array.
    907          * @param array the array, assumed to be unmodified during use
    908          * @param additionalCharacteristics Additional spliterator characteristics
    909          * of this spliterator's source or elements beyond {@code SIZED} and
    910          * {@code SUBSIZED} which are are always reported
    911          */
    912         public ArraySpliterator(Object[] array, int additionalCharacteristics) {
    913             this(array, 0, array.length, additionalCharacteristics);
    914         }
    915 
    916         /**
    917          * Creates a spliterator covering the given array and range
    918          * @param array the array, assumed to be unmodified during use
    919          * @param origin the least index (inclusive) to cover
    920          * @param fence one past the greatest index to cover
    921          * @param additionalCharacteristics Additional spliterator characteristics
    922          * of this spliterator's source or elements beyond {@code SIZED} and
    923          * {@code SUBSIZED} which are are always reported
    924          */
    925         public ArraySpliterator(Object[] array, int origin, int fence, int additionalCharacteristics) {
    926             this.array = array;
    927             this.index = origin;
    928             this.fence = fence;
    929             this.characteristics = additionalCharacteristics | Spliterator.SIZED | Spliterator.SUBSIZED;
    930         }
    931 
    932         @Override
    933         public Spliterator<T> trySplit() {
    934             int lo = index, mid = (lo + fence) >>> 1;
    935             return (lo >= mid)
    936                    ? null
    937                    : new ArraySpliterator<>(array, lo, index = mid, characteristics);
    938         }
    939 
    940         @SuppressWarnings("unchecked")
    941         @Override
    942         public void forEachRemaining(Consumer<? super T> action) {
    943             Object[] a; int i, hi; // hoist accesses and checks from loop
    944             if (action == null)
    945                 throw new NullPointerException();
    946             if ((a = array).length >= (hi = fence) &&
    947                 (i = index) >= 0 && i < (index = hi)) {
    948                 do { action.accept((T)a[i]); } while (++i < hi);
    949             }
    950         }
    951 
    952         @Override
    953         public boolean tryAdvance(Consumer<? super T> action) {
    954             if (action == null)
    955                 throw new NullPointerException();
    956             if (index >= 0 && index < fence) {
    957                 @SuppressWarnings("unchecked") T e = (T) array[index++];
    958                 action.accept(e);
    959                 return true;
    960             }
    961             return false;
    962         }
    963 
    964         @Override
    965         public long estimateSize() { return (long)(fence - index); }
    966 
    967         @Override
    968         public int characteristics() {
    969             return characteristics;
    970         }
    971 
    972         @Override
    973         public Comparator<? super T> getComparator() {
    974             if (hasCharacteristics(Spliterator.SORTED))
    975                 return null;
    976             throw new IllegalStateException();
    977         }
    978     }
    979 
    980     /**
    981      * A Spliterator.OfInt designed for use by sources that traverse and split
    982      * elements maintained in an unmodifiable {@code int[]} array.
    983      */
    984     static final class IntArraySpliterator implements Spliterator.OfInt {
    985         private final int[] array;
    986         private int index;        // current index, modified on advance/split
    987         private final int fence;  // one past last index
    988         private final int characteristics;
    989 
    990         /**
    991          * Creates a spliterator covering all of the given array.
    992          * @param array the array, assumed to be unmodified during use
    993          * @param additionalCharacteristics Additional spliterator characteristics
    994          *        of this spliterator's source or elements beyond {@code SIZED} and
    995          *        {@code SUBSIZED} which are are always reported
    996          */
    997         public IntArraySpliterator(int[] array, int additionalCharacteristics) {
    998             this(array, 0, array.length, additionalCharacteristics);
    999         }
   1000 
   1001         /**
   1002          * Creates a spliterator covering the given array and range
   1003          * @param array the array, assumed to be unmodified during use
   1004          * @param origin the least index (inclusive) to cover
   1005          * @param fence one past the greatest index to cover
   1006          * @param additionalCharacteristics Additional spliterator characteristics
   1007          *        of this spliterator's source or elements beyond {@code SIZED} and
   1008          *        {@code SUBSIZED} which are are always reported
   1009          */
   1010         public IntArraySpliterator(int[] array, int origin, int fence, int additionalCharacteristics) {
   1011             this.array = array;
   1012             this.index = origin;
   1013             this.fence = fence;
   1014             this.characteristics = additionalCharacteristics | Spliterator.SIZED | Spliterator.SUBSIZED;
   1015         }
   1016 
   1017         @Override
   1018         public OfInt trySplit() {
   1019             int lo = index, mid = (lo + fence) >>> 1;
   1020             return (lo >= mid)
   1021                    ? null
   1022                    : new IntArraySpliterator(array, lo, index = mid, characteristics);
   1023         }
   1024 
   1025         @Override
   1026         public void forEachRemaining(IntConsumer action) {
   1027             int[] a; int i, hi; // hoist accesses and checks from loop
   1028             if (action == null)
   1029                 throw new NullPointerException();
   1030             if ((a = array).length >= (hi = fence) &&
   1031                 (i = index) >= 0 && i < (index = hi)) {
   1032                 do { action.accept(a[i]); } while (++i < hi);
   1033             }
   1034         }
   1035 
   1036         @Override
   1037         public boolean tryAdvance(IntConsumer action) {
   1038             if (action == null)
   1039                 throw new NullPointerException();
   1040             if (index >= 0 && index < fence) {
   1041                 action.accept(array[index++]);
   1042                 return true;
   1043             }
   1044             return false;
   1045         }
   1046 
   1047         @Override
   1048         public long estimateSize() { return (long)(fence - index); }
   1049 
   1050         @Override
   1051         public int characteristics() {
   1052             return characteristics;
   1053         }
   1054 
   1055         @Override
   1056         public Comparator<? super Integer> getComparator() {
   1057             if (hasCharacteristics(Spliterator.SORTED))
   1058                 return null;
   1059             throw new IllegalStateException();
   1060         }
   1061     }
   1062 
   1063     /**
   1064      * A Spliterator.OfLong designed for use by sources that traverse and split
   1065      * elements maintained in an unmodifiable {@code int[]} array.
   1066      */
   1067     static final class LongArraySpliterator implements Spliterator.OfLong {
   1068         private final long[] array;
   1069         private int index;        // current index, modified on advance/split
   1070         private final int fence;  // one past last index
   1071         private final int characteristics;
   1072 
   1073         /**
   1074          * Creates a spliterator covering all of the given array.
   1075          * @param array the array, assumed to be unmodified during use
   1076          * @param additionalCharacteristics Additional spliterator characteristics
   1077          *        of this spliterator's source or elements beyond {@code SIZED} and
   1078          *        {@code SUBSIZED} which are are always reported
   1079          */
   1080         public LongArraySpliterator(long[] array, int additionalCharacteristics) {
   1081             this(array, 0, array.length, additionalCharacteristics);
   1082         }
   1083 
   1084         /**
   1085          * Creates a spliterator covering the given array and range
   1086          * @param array the array, assumed to be unmodified during use
   1087          * @param origin the least index (inclusive) to cover
   1088          * @param fence one past the greatest index to cover
   1089          * @param additionalCharacteristics Additional spliterator characteristics
   1090          *        of this spliterator's source or elements beyond {@code SIZED} and
   1091          *        {@code SUBSIZED} which are are always reported
   1092          */
   1093         public LongArraySpliterator(long[] array, int origin, int fence, int additionalCharacteristics) {
   1094             this.array = array;
   1095             this.index = origin;
   1096             this.fence = fence;
   1097             this.characteristics = additionalCharacteristics | Spliterator.SIZED | Spliterator.SUBSIZED;
   1098         }
   1099 
   1100         @Override
   1101         public OfLong trySplit() {
   1102             int lo = index, mid = (lo + fence) >>> 1;
   1103             return (lo >= mid)
   1104                    ? null
   1105                    : new LongArraySpliterator(array, lo, index = mid, characteristics);
   1106         }
   1107 
   1108         @Override
   1109         public void forEachRemaining(LongConsumer action) {
   1110             long[] a; int i, hi; // hoist accesses and checks from loop
   1111             if (action == null)
   1112                 throw new NullPointerException();
   1113             if ((a = array).length >= (hi = fence) &&
   1114                 (i = index) >= 0 && i < (index = hi)) {
   1115                 do { action.accept(a[i]); } while (++i < hi);
   1116             }
   1117         }
   1118 
   1119         @Override
   1120         public boolean tryAdvance(LongConsumer action) {
   1121             if (action == null)
   1122                 throw new NullPointerException();
   1123             if (index >= 0 && index < fence) {
   1124                 action.accept(array[index++]);
   1125                 return true;
   1126             }
   1127             return false;
   1128         }
   1129 
   1130         @Override
   1131         public long estimateSize() { return (long)(fence - index); }
   1132 
   1133         @Override
   1134         public int characteristics() {
   1135             return characteristics;
   1136         }
   1137 
   1138         @Override
   1139         public Comparator<? super Long> getComparator() {
   1140             if (hasCharacteristics(Spliterator.SORTED))
   1141                 return null;
   1142             throw new IllegalStateException();
   1143         }
   1144     }
   1145 
   1146     /**
   1147      * A Spliterator.OfDouble designed for use by sources that traverse and split
   1148      * elements maintained in an unmodifiable {@code int[]} array.
   1149      */
   1150     static final class DoubleArraySpliterator implements Spliterator.OfDouble {
   1151         private final double[] array;
   1152         private int index;        // current index, modified on advance/split
   1153         private final int fence;  // one past last index
   1154         private final int characteristics;
   1155 
   1156         /**
   1157          * Creates a spliterator covering all of the given array.
   1158          * @param array the array, assumed to be unmodified during use
   1159          * @param additionalCharacteristics Additional spliterator characteristics
   1160          *        of this spliterator's source or elements beyond {@code SIZED} and
   1161          *        {@code SUBSIZED} which are are always reported
   1162          */
   1163         public DoubleArraySpliterator(double[] array, int additionalCharacteristics) {
   1164             this(array, 0, array.length, additionalCharacteristics);
   1165         }
   1166 
   1167         /**
   1168          * Creates a spliterator covering the given array and range
   1169          * @param array the array, assumed to be unmodified during use
   1170          * @param origin the least index (inclusive) to cover
   1171          * @param fence one past the greatest index to cover
   1172          * @param additionalCharacteristics Additional spliterator characteristics
   1173          *        of this spliterator's source or elements beyond {@code SIZED} and
   1174          *        {@code SUBSIZED} which are are always reported
   1175          */
   1176         public DoubleArraySpliterator(double[] array, int origin, int fence, int additionalCharacteristics) {
   1177             this.array = array;
   1178             this.index = origin;
   1179             this.fence = fence;
   1180             this.characteristics = additionalCharacteristics | Spliterator.SIZED | Spliterator.SUBSIZED;
   1181         }
   1182 
   1183         @Override
   1184         public OfDouble trySplit() {
   1185             int lo = index, mid = (lo + fence) >>> 1;
   1186             return (lo >= mid)
   1187                    ? null
   1188                    : new DoubleArraySpliterator(array, lo, index = mid, characteristics);
   1189         }
   1190 
   1191         @Override
   1192         public void forEachRemaining(DoubleConsumer action) {
   1193             double[] a; int i, hi; // hoist accesses and checks from loop
   1194             if (action == null)
   1195                 throw new NullPointerException();
   1196             if ((a = array).length >= (hi = fence) &&
   1197                 (i = index) >= 0 && i < (index = hi)) {
   1198                 do { action.accept(a[i]); } while (++i < hi);
   1199             }
   1200         }
   1201 
   1202         @Override
   1203         public boolean tryAdvance(DoubleConsumer action) {
   1204             if (action == null)
   1205                 throw new NullPointerException();
   1206             if (index >= 0 && index < fence) {
   1207                 action.accept(array[index++]);
   1208                 return true;
   1209             }
   1210             return false;
   1211         }
   1212 
   1213         @Override
   1214         public long estimateSize() { return (long)(fence - index); }
   1215 
   1216         @Override
   1217         public int characteristics() {
   1218             return characteristics;
   1219         }
   1220 
   1221         @Override
   1222         public Comparator<? super Double> getComparator() {
   1223             if (hasCharacteristics(Spliterator.SORTED))
   1224                 return null;
   1225             throw new IllegalStateException();
   1226         }
   1227     }
   1228 
   1229     //
   1230 
   1231     /**
   1232      * An abstract {@code Spliterator} that implements {@code trySplit} to
   1233      * permit limited parallelism.
   1234      *
   1235      * <p>An extending class need only
   1236      * implement {@link #tryAdvance(java.util.function.Consumer) tryAdvance}.
   1237      * The extending class should override
   1238      * {@link #forEachRemaining(java.util.function.Consumer) forEach} if it can
   1239      * provide a more performant implementation.
   1240      *
   1241      * @apiNote
   1242      * This class is a useful aid for creating a spliterator when it is not
   1243      * possible or difficult to efficiently partition elements in a manner
   1244      * allowing balanced parallel computation.
   1245      *
   1246      * <p>An alternative to using this class, that also permits limited
   1247      * parallelism, is to create a spliterator from an iterator
   1248      * (see {@link #spliterator(Iterator, long, int)}.  Depending on the
   1249      * circumstances using an iterator may be easier or more convenient than
   1250      * extending this class, such as when there is already an iterator
   1251      * available to use.
   1252      *
   1253      * @see #spliterator(Iterator, long, int)
   1254      * @since 1.8
   1255      */
   1256     public static abstract class AbstractSpliterator<T> implements Spliterator<T> {
   1257         static final int BATCH_UNIT = 1 << 10;  // batch array size increment
   1258         static final int MAX_BATCH = 1 << 25;  // max batch array size;
   1259         private final int characteristics;
   1260         private long est;             // size estimate
   1261         private int batch;            // batch size for splits
   1262 
   1263         /**
   1264          * Creates a spliterator reporting the given estimated size and
   1265          * additionalCharacteristics.
   1266          *
   1267          * @param est the estimated size of this spliterator if known, otherwise
   1268          *        {@code Long.MAX_VALUE}.
   1269          * @param additionalCharacteristics properties of this spliterator's
   1270          *        source or elements.  If {@code SIZED} is reported then this
   1271          *        spliterator will additionally report {@code SUBSIZED}.
   1272          */
   1273         protected AbstractSpliterator(long est, int additionalCharacteristics) {
   1274             this.est = est;
   1275             this.characteristics = ((additionalCharacteristics & Spliterator.SIZED) != 0)
   1276                                    ? additionalCharacteristics | Spliterator.SUBSIZED
   1277                                    : additionalCharacteristics;
   1278         }
   1279 
   1280         static final class HoldingConsumer<T> implements Consumer<T> {
   1281             Object value;
   1282 
   1283             @Override
   1284             public void accept(T value) {
   1285                 this.value = value;
   1286             }
   1287         }
   1288 
   1289         /**
   1290          * {@inheritDoc}
   1291          *
   1292          * This implementation permits limited parallelism.
   1293          */
   1294         @Override
   1295         public Spliterator<T> trySplit() {
   1296             /*
   1297              * Split into arrays of arithmetically increasing batch
   1298              * sizes.  This will only improve parallel performance if
   1299              * per-element Consumer actions are more costly than
   1300              * transferring them into an array.  The use of an
   1301              * arithmetic progression in split sizes provides overhead
   1302              * vs parallelism bounds that do not particularly favor or
   1303              * penalize cases of lightweight vs heavyweight element
   1304              * operations, across combinations of #elements vs #cores,
   1305              * whether or not either are known.  We generate
   1306              * O(sqrt(#elements)) splits, allowing O(sqrt(#cores))
   1307              * potential speedup.
   1308              */
   1309             HoldingConsumer<T> holder = new HoldingConsumer<>();
   1310             long s = est;
   1311             if (s > 1 && tryAdvance(holder)) {
   1312                 int n = batch + BATCH_UNIT;
   1313                 if (n > s)
   1314                     n = (int) s;
   1315                 if (n > MAX_BATCH)
   1316                     n = MAX_BATCH;
   1317                 Object[] a = new Object[n];
   1318                 int j = 0;
   1319                 do { a[j] = holder.value; } while (++j < n && tryAdvance(holder));
   1320                 batch = j;
   1321                 if (est != Long.MAX_VALUE)
   1322                     est -= j;
   1323                 return new ArraySpliterator<>(a, 0, j, characteristics());
   1324             }
   1325             return null;
   1326         }
   1327 
   1328         /**
   1329          * {@inheritDoc}
   1330          *
   1331          * @implSpec
   1332          * This implementation returns the estimated size as reported when
   1333          * created and, if the estimate size is known, decreases in size when
   1334          * split.
   1335          */
   1336         @Override
   1337         public long estimateSize() {
   1338             return est;
   1339         }
   1340 
   1341         /**
   1342          * {@inheritDoc}
   1343          *
   1344          * @implSpec
   1345          * This implementation returns the characteristics as reported when
   1346          * created.
   1347          */
   1348         @Override
   1349         public int characteristics() {
   1350             return characteristics;
   1351         }
   1352     }
   1353 
   1354     /**
   1355      * An abstract {@code Spliterator.OfInt} that implements {@code trySplit} to
   1356      * permit limited parallelism.
   1357      *
   1358      * <p>To implement a spliterator an extending class need only
   1359      * implement {@link #tryAdvance(java.util.function.IntConsumer)}
   1360      * tryAdvance}.  The extending class should override
   1361      * {@link #forEachRemaining(java.util.function.IntConsumer)} forEach} if it
   1362      * can provide a more performant implementation.
   1363      *
   1364      * @apiNote
   1365      * This class is a useful aid for creating a spliterator when it is not
   1366      * possible or difficult to efficiently partition elements in a manner
   1367      * allowing balanced parallel computation.
   1368      *
   1369      * <p>An alternative to using this class, that also permits limited
   1370      * parallelism, is to create a spliterator from an iterator
   1371      * (see {@link #spliterator(java.util.PrimitiveIterator.OfInt, long, int)}.
   1372      * Depending on the circumstances using an iterator may be easier or more
   1373      * convenient than extending this class. For example, if there is already an
   1374      * iterator available to use then there is no need to extend this class.
   1375      *
   1376      * @see #spliterator(java.util.PrimitiveIterator.OfInt, long, int)
   1377      * @since 1.8
   1378      */
   1379     public static abstract class AbstractIntSpliterator implements Spliterator.OfInt {
   1380         static final int MAX_BATCH = AbstractSpliterator.MAX_BATCH;
   1381         static final int BATCH_UNIT = AbstractSpliterator.BATCH_UNIT;
   1382         private final int characteristics;
   1383         private long est;             // size estimate
   1384         private int batch;            // batch size for splits
   1385 
   1386         /**
   1387          * Creates a spliterator reporting the given estimated size and
   1388          * characteristics.
   1389          *
   1390          * @param est the estimated size of this spliterator if known, otherwise
   1391          *        {@code Long.MAX_VALUE}.
   1392          * @param additionalCharacteristics properties of this spliterator's
   1393          *        source or elements.  If {@code SIZED} is reported then this
   1394          *        spliterator will additionally report {@code SUBSIZED}.
   1395          */
   1396         protected AbstractIntSpliterator(long est, int additionalCharacteristics) {
   1397             this.est = est;
   1398             this.characteristics = ((additionalCharacteristics & Spliterator.SIZED) != 0)
   1399                                    ? additionalCharacteristics | Spliterator.SUBSIZED
   1400                                    : additionalCharacteristics;
   1401         }
   1402 
   1403         static final class HoldingIntConsumer implements IntConsumer {
   1404             int value;
   1405 
   1406             @Override
   1407             public void accept(int value) {
   1408                 this.value = value;
   1409             }
   1410         }
   1411 
   1412         /**
   1413          * {@inheritDoc}
   1414          *
   1415          * This implementation permits limited parallelism.
   1416          */
   1417         @Override
   1418         public Spliterator.OfInt trySplit() {
   1419             HoldingIntConsumer holder = new HoldingIntConsumer();
   1420             long s = est;
   1421             if (s > 1 && tryAdvance(holder)) {
   1422                 int n = batch + BATCH_UNIT;
   1423                 if (n > s)
   1424                     n = (int) s;
   1425                 if (n > MAX_BATCH)
   1426                     n = MAX_BATCH;
   1427                 int[] a = new int[n];
   1428                 int j = 0;
   1429                 do { a[j] = holder.value; } while (++j < n && tryAdvance(holder));
   1430                 batch = j;
   1431                 if (est != Long.MAX_VALUE)
   1432                     est -= j;
   1433                 return new IntArraySpliterator(a, 0, j, characteristics());
   1434             }
   1435             return null;
   1436         }
   1437 
   1438         /**
   1439          * {@inheritDoc}
   1440          *
   1441          * @implSpec
   1442          * This implementation returns the estimated size as reported when
   1443          * created and, if the estimate size is known, decreases in size when
   1444          * split.
   1445          */
   1446         @Override
   1447         public long estimateSize() {
   1448             return est;
   1449         }
   1450 
   1451         /**
   1452          * {@inheritDoc}
   1453          *
   1454          * @implSpec
   1455          * This implementation returns the characteristics as reported when
   1456          * created.
   1457          */
   1458         @Override
   1459         public int characteristics() {
   1460             return characteristics;
   1461         }
   1462     }
   1463 
   1464     /**
   1465      * An abstract {@code Spliterator.OfLong} that implements {@code trySplit}
   1466      * to permit limited parallelism.
   1467      *
   1468      * <p>To implement a spliterator an extending class need only
   1469      * implement {@link #tryAdvance(java.util.function.LongConsumer)}
   1470      * tryAdvance}.  The extending class should override
   1471      * {@link #forEachRemaining(java.util.function.LongConsumer)} forEach} if it
   1472      * can provide a more performant implementation.
   1473      *
   1474      * @apiNote
   1475      * This class is a useful aid for creating a spliterator when it is not
   1476      * possible or difficult to efficiently partition elements in a manner
   1477      * allowing balanced parallel computation.
   1478      *
   1479      * <p>An alternative to using this class, that also permits limited
   1480      * parallelism, is to create a spliterator from an iterator
   1481      * (see {@link #spliterator(java.util.PrimitiveIterator.OfLong, long, int)}.
   1482      * Depending on the circumstances using an iterator may be easier or more
   1483      * convenient than extending this class. For example, if there is already an
   1484      * iterator available to use then there is no need to extend this class.
   1485      *
   1486      * @see #spliterator(java.util.PrimitiveIterator.OfLong, long, int)
   1487      * @since 1.8
   1488      */
   1489     public static abstract class AbstractLongSpliterator implements Spliterator.OfLong {
   1490         static final int MAX_BATCH = AbstractSpliterator.MAX_BATCH;
   1491         static final int BATCH_UNIT = AbstractSpliterator.BATCH_UNIT;
   1492         private final int characteristics;
   1493         private long est;             // size estimate
   1494         private int batch;            // batch size for splits
   1495 
   1496         /**
   1497          * Creates a spliterator reporting the given estimated size and
   1498          * characteristics.
   1499          *
   1500          * @param est the estimated size of this spliterator if known, otherwise
   1501          *        {@code Long.MAX_VALUE}.
   1502          * @param additionalCharacteristics properties of this spliterator's
   1503          *        source or elements.  If {@code SIZED} is reported then this
   1504          *        spliterator will additionally report {@code SUBSIZED}.
   1505          */
   1506         protected AbstractLongSpliterator(long est, int additionalCharacteristics) {
   1507             this.est = est;
   1508             this.characteristics = ((additionalCharacteristics & Spliterator.SIZED) != 0)
   1509                                    ? additionalCharacteristics | Spliterator.SUBSIZED
   1510                                    : additionalCharacteristics;
   1511         }
   1512 
   1513         static final class HoldingLongConsumer implements LongConsumer {
   1514             long value;
   1515 
   1516             @Override
   1517             public void accept(long value) {
   1518                 this.value = value;
   1519             }
   1520         }
   1521 
   1522         /**
   1523          * {@inheritDoc}
   1524          *
   1525          * This implementation permits limited parallelism.
   1526          */
   1527         @Override
   1528         public Spliterator.OfLong trySplit() {
   1529             HoldingLongConsumer holder = new HoldingLongConsumer();
   1530             long s = est;
   1531             if (s > 1 && tryAdvance(holder)) {
   1532                 int n = batch + BATCH_UNIT;
   1533                 if (n > s)
   1534                     n = (int) s;
   1535                 if (n > MAX_BATCH)
   1536                     n = MAX_BATCH;
   1537                 long[] a = new long[n];
   1538                 int j = 0;
   1539                 do { a[j] = holder.value; } while (++j < n && tryAdvance(holder));
   1540                 batch = j;
   1541                 if (est != Long.MAX_VALUE)
   1542                     est -= j;
   1543                 return new LongArraySpliterator(a, 0, j, characteristics());
   1544             }
   1545             return null;
   1546         }
   1547 
   1548         /**
   1549          * {@inheritDoc}
   1550          *
   1551          * @implSpec
   1552          * This implementation returns the estimated size as reported when
   1553          * created and, if the estimate size is known, decreases in size when
   1554          * split.
   1555          */
   1556         @Override
   1557         public long estimateSize() {
   1558             return est;
   1559         }
   1560 
   1561         /**
   1562          * {@inheritDoc}
   1563          *
   1564          * @implSpec
   1565          * This implementation returns the characteristics as reported when
   1566          * created.
   1567          */
   1568         @Override
   1569         public int characteristics() {
   1570             return characteristics;
   1571         }
   1572     }
   1573 
   1574     /**
   1575      * An abstract {@code Spliterator.OfDouble} that implements
   1576      * {@code trySplit} to permit limited parallelism.
   1577      *
   1578      * <p>To implement a spliterator an extending class need only
   1579      * implement {@link #tryAdvance(java.util.function.DoubleConsumer)}
   1580      * tryAdvance}.  The extending class should override
   1581      * {@link #forEachRemaining(java.util.function.DoubleConsumer)} forEach} if
   1582      * it can provide a more performant implementation.
   1583      *
   1584      * @apiNote
   1585      * This class is a useful aid for creating a spliterator when it is not
   1586      * possible or difficult to efficiently partition elements in a manner
   1587      * allowing balanced parallel computation.
   1588      *
   1589      * <p>An alternative to using this class, that also permits limited
   1590      * parallelism, is to create a spliterator from an iterator
   1591      * (see {@link #spliterator(java.util.PrimitiveIterator.OfDouble, long, int)}.
   1592      * Depending on the circumstances using an iterator may be easier or more
   1593      * convenient than extending this class. For example, if there is already an
   1594      * iterator available to use then there is no need to extend this class.
   1595      *
   1596      * @see #spliterator(java.util.PrimitiveIterator.OfDouble, long, int)
   1597      * @since 1.8
   1598      */
   1599     public static abstract class AbstractDoubleSpliterator implements Spliterator.OfDouble {
   1600         static final int MAX_BATCH = AbstractSpliterator.MAX_BATCH;
   1601         static final int BATCH_UNIT = AbstractSpliterator.BATCH_UNIT;
   1602         private final int characteristics;
   1603         private long est;             // size estimate
   1604         private int batch;            // batch size for splits
   1605 
   1606         /**
   1607          * Creates a spliterator reporting the given estimated size and
   1608          * characteristics.
   1609          *
   1610          * @param est the estimated size of this spliterator if known, otherwise
   1611          *        {@code Long.MAX_VALUE}.
   1612          * @param additionalCharacteristics properties of this spliterator's
   1613          *        source or elements.  If {@code SIZED} is reported then this
   1614          *        spliterator will additionally report {@code SUBSIZED}.
   1615          */
   1616         protected AbstractDoubleSpliterator(long est, int additionalCharacteristics) {
   1617             this.est = est;
   1618             this.characteristics = ((additionalCharacteristics & Spliterator.SIZED) != 0)
   1619                                    ? additionalCharacteristics | Spliterator.SUBSIZED
   1620                                    : additionalCharacteristics;
   1621         }
   1622 
   1623         static final class HoldingDoubleConsumer implements DoubleConsumer {
   1624             double value;
   1625 
   1626             @Override
   1627             public void accept(double value) {
   1628                 this.value = value;
   1629             }
   1630         }
   1631 
   1632         /**
   1633          * {@inheritDoc}
   1634          *
   1635          * This implementation permits limited parallelism.
   1636          */
   1637         @Override
   1638         public Spliterator.OfDouble trySplit() {
   1639             HoldingDoubleConsumer holder = new HoldingDoubleConsumer();
   1640             long s = est;
   1641             if (s > 1 && tryAdvance(holder)) {
   1642                 int n = batch + BATCH_UNIT;
   1643                 if (n > s)
   1644                     n = (int) s;
   1645                 if (n > MAX_BATCH)
   1646                     n = MAX_BATCH;
   1647                 double[] a = new double[n];
   1648                 int j = 0;
   1649                 do { a[j] = holder.value; } while (++j < n && tryAdvance(holder));
   1650                 batch = j;
   1651                 if (est != Long.MAX_VALUE)
   1652                     est -= j;
   1653                 return new DoubleArraySpliterator(a, 0, j, characteristics());
   1654             }
   1655             return null;
   1656         }
   1657 
   1658         /**
   1659          * {@inheritDoc}
   1660          *
   1661          * @implSpec
   1662          * This implementation returns the estimated size as reported when
   1663          * created and, if the estimate size is known, decreases in size when
   1664          * split.
   1665          */
   1666         @Override
   1667         public long estimateSize() {
   1668             return est;
   1669         }
   1670 
   1671         /**
   1672          * {@inheritDoc}
   1673          *
   1674          * @implSpec
   1675          * This implementation returns the characteristics as reported when
   1676          * created.
   1677          */
   1678         @Override
   1679         public int characteristics() {
   1680             return characteristics;
   1681         }
   1682     }
   1683 
   1684     // Iterator-based Spliterators
   1685 
   1686     /**
   1687      * A Spliterator using a given Iterator for element
   1688      * operations. The spliterator implements {@code trySplit} to
   1689      * permit limited parallelism.
   1690      */
   1691     static class IteratorSpliterator<T> implements Spliterator<T> {
   1692         static final int BATCH_UNIT = 1 << 10;  // batch array size increment
   1693         static final int MAX_BATCH = 1 << 25;  // max batch array size;
   1694         private final Collection<? extends T> collection; // null OK
   1695         private Iterator<? extends T> it;
   1696         private final int characteristics;
   1697         private long est;             // size estimate
   1698         private int batch;            // batch size for splits
   1699 
   1700         /**
   1701          * Creates a spliterator using the given given
   1702          * collection's {@link java.util.Collection#iterator()) for traversal,
   1703          * and reporting its {@link java.util.Collection#size()) as its initial
   1704          * size.
   1705          *
   1706          * @param c the collection
   1707          * @param characteristics properties of this spliterator's
   1708          *        source or elements.
   1709          */
   1710         public IteratorSpliterator(Collection<? extends T> collection, int characteristics) {
   1711             this.collection = collection;
   1712             this.it = null;
   1713             this.characteristics = (characteristics & Spliterator.CONCURRENT) == 0
   1714                                    ? characteristics | Spliterator.SIZED | Spliterator.SUBSIZED
   1715                                    : characteristics;
   1716         }
   1717 
   1718         /**
   1719          * Creates a spliterator using the given iterator
   1720          * for traversal, and reporting the given initial size
   1721          * and characteristics.
   1722          *
   1723          * @param iterator the iterator for the source
   1724          * @param size the number of elements in the source
   1725          * @param characteristics properties of this spliterator's
   1726          * source or elements.
   1727          */
   1728         public IteratorSpliterator(Iterator<? extends T> iterator, long size, int characteristics) {
   1729             this.collection = null;
   1730             this.it = iterator;
   1731             this.est = size;
   1732             this.characteristics = (characteristics & Spliterator.CONCURRENT) == 0
   1733                                    ? characteristics | Spliterator.SIZED | Spliterator.SUBSIZED
   1734                                    : characteristics;
   1735         }
   1736 
   1737         /**
   1738          * Creates a spliterator using the given iterator
   1739          * for traversal, and reporting the given initial size
   1740          * and characteristics.
   1741          *
   1742          * @param iterator the iterator for the source
   1743          * @param characteristics properties of this spliterator's
   1744          * source or elements.
   1745          */
   1746         public IteratorSpliterator(Iterator<? extends T> iterator, int characteristics) {
   1747             this.collection = null;
   1748             this.it = iterator;
   1749             this.est = Long.MAX_VALUE;
   1750             this.characteristics = characteristics & ~(Spliterator.SIZED | Spliterator.SUBSIZED);
   1751         }
   1752 
   1753         @Override
   1754         public Spliterator<T> trySplit() {
   1755             /*
   1756              * Split into arrays of arithmetically increasing batch
   1757              * sizes.  This will only improve parallel performance if
   1758              * per-element Consumer actions are more costly than
   1759              * transferring them into an array.  The use of an
   1760              * arithmetic progression in split sizes provides overhead
   1761              * vs parallelism bounds that do not particularly favor or
   1762              * penalize cases of lightweight vs heavyweight element
   1763              * operations, across combinations of #elements vs #cores,
   1764              * whether or not either are known.  We generate
   1765              * O(sqrt(#elements)) splits, allowing O(sqrt(#cores))
   1766              * potential speedup.
   1767              */
   1768             Iterator<? extends T> i;
   1769             long s;
   1770             if ((i = it) == null) {
   1771                 i = it = collection.iterator();
   1772                 s = est = (long) collection.size();
   1773             }
   1774             else
   1775                 s = est;
   1776             if (s > 1 && i.hasNext()) {
   1777                 int n = batch + BATCH_UNIT;
   1778                 if (n > s)
   1779                     n = (int) s;
   1780                 if (n > MAX_BATCH)
   1781                     n = MAX_BATCH;
   1782                 Object[] a = new Object[n];
   1783                 int j = 0;
   1784                 do { a[j] = i.next(); } while (++j < n && i.hasNext());
   1785                 batch = j;
   1786                 if (est != Long.MAX_VALUE)
   1787                     est -= j;
   1788                 return new ArraySpliterator<>(a, 0, j, characteristics);
   1789             }
   1790             return null;
   1791         }
   1792 
   1793         @Override
   1794         public void forEachRemaining(Consumer<? super T> action) {
   1795             if (action == null) throw new NullPointerException();
   1796             Iterator<? extends T> i;
   1797             if ((i = it) == null) {
   1798                 i = it = collection.iterator();
   1799                 est = (long)collection.size();
   1800             }
   1801             i.forEachRemaining(action);
   1802         }
   1803 
   1804         @Override
   1805         public boolean tryAdvance(Consumer<? super T> action) {
   1806             if (action == null) throw new NullPointerException();
   1807             if (it == null) {
   1808                 it = collection.iterator();
   1809                 est = (long) collection.size();
   1810             }
   1811             if (it.hasNext()) {
   1812                 action.accept(it.next());
   1813                 return true;
   1814             }
   1815             return false;
   1816         }
   1817 
   1818         @Override
   1819         public long estimateSize() {
   1820             if (it == null) {
   1821                 it = collection.iterator();
   1822                 return est = (long)collection.size();
   1823             }
   1824             return est;
   1825         }
   1826 
   1827         @Override
   1828         public int characteristics() { return characteristics; }
   1829 
   1830         @Override
   1831         public Comparator<? super T> getComparator() {
   1832             if (hasCharacteristics(Spliterator.SORTED))
   1833                 return null;
   1834             throw new IllegalStateException();
   1835         }
   1836     }
   1837 
   1838     /**
   1839      * A Spliterator.OfInt using a given IntStream.IntIterator for element
   1840      * operations. The spliterator implements {@code trySplit} to
   1841      * permit limited parallelism.
   1842      */
   1843     static final class IntIteratorSpliterator implements Spliterator.OfInt {
   1844         static final int BATCH_UNIT = IteratorSpliterator.BATCH_UNIT;
   1845         static final int MAX_BATCH = IteratorSpliterator.MAX_BATCH;
   1846         private PrimitiveIterator.OfInt it;
   1847         private final int characteristics;
   1848         private long est;             // size estimate
   1849         private int batch;            // batch size for splits
   1850 
   1851         /**
   1852          * Creates a spliterator using the given iterator
   1853          * for traversal, and reporting the given initial size
   1854          * and characteristics.
   1855          *
   1856          * @param iterator the iterator for the source
   1857          * @param size the number of elements in the source
   1858          * @param characteristics properties of this spliterator's
   1859          * source or elements.
   1860          */
   1861         public IntIteratorSpliterator(PrimitiveIterator.OfInt iterator, long size, int characteristics) {
   1862             this.it = iterator;
   1863             this.est = size;
   1864             this.characteristics = (characteristics & Spliterator.CONCURRENT) == 0
   1865                                    ? characteristics | Spliterator.SIZED | Spliterator.SUBSIZED
   1866                                    : characteristics;
   1867         }
   1868 
   1869         /**
   1870          * Creates a spliterator using the given iterator for a
   1871          * source of unknown size, reporting the given
   1872          * characteristics.
   1873          *
   1874          * @param iterator the iterator for the source
   1875          * @param characteristics properties of this spliterator's
   1876          * source or elements.
   1877          */
   1878         public IntIteratorSpliterator(PrimitiveIterator.OfInt iterator, int characteristics) {
   1879             this.it = iterator;
   1880             this.est = Long.MAX_VALUE;
   1881             this.characteristics = characteristics & ~(Spliterator.SIZED | Spliterator.SUBSIZED);
   1882         }
   1883 
   1884         @Override
   1885         public OfInt trySplit() {
   1886             PrimitiveIterator.OfInt i = it;
   1887             long s = est;
   1888             if (s > 1 && i.hasNext()) {
   1889                 int n = batch + BATCH_UNIT;
   1890                 if (n > s)
   1891                     n = (int) s;
   1892                 if (n > MAX_BATCH)
   1893                     n = MAX_BATCH;
   1894                 int[] a = new int[n];
   1895                 int j = 0;
   1896                 do { a[j] = i.nextInt(); } while (++j < n && i.hasNext());
   1897                 batch = j;
   1898                 if (est != Long.MAX_VALUE)
   1899                     est -= j;
   1900                 return new IntArraySpliterator(a, 0, j, characteristics);
   1901             }
   1902             return null;
   1903         }
   1904 
   1905         @Override
   1906         public void forEachRemaining(IntConsumer action) {
   1907             if (action == null) throw new NullPointerException();
   1908             it.forEachRemaining(action);
   1909         }
   1910 
   1911         @Override
   1912         public boolean tryAdvance(IntConsumer action) {
   1913             if (action == null) throw new NullPointerException();
   1914             if (it.hasNext()) {
   1915                 action.accept(it.nextInt());
   1916                 return true;
   1917             }
   1918             return false;
   1919         }
   1920 
   1921         @Override
   1922         public long estimateSize() {
   1923             return est;
   1924         }
   1925 
   1926         @Override
   1927         public int characteristics() { return characteristics; }
   1928 
   1929         @Override
   1930         public Comparator<? super Integer> getComparator() {
   1931             if (hasCharacteristics(Spliterator.SORTED))
   1932                 return null;
   1933             throw new IllegalStateException();
   1934         }
   1935     }
   1936 
   1937     static final class LongIteratorSpliterator implements Spliterator.OfLong {
   1938         static final int BATCH_UNIT = IteratorSpliterator.BATCH_UNIT;
   1939         static final int MAX_BATCH = IteratorSpliterator.MAX_BATCH;
   1940         private PrimitiveIterator.OfLong it;
   1941         private final int characteristics;
   1942         private long est;             // size estimate
   1943         private int batch;            // batch size for splits
   1944 
   1945         /**
   1946          * Creates a spliterator using the given iterator
   1947          * for traversal, and reporting the given initial size
   1948          * and characteristics.
   1949          *
   1950          * @param iterator the iterator for the source
   1951          * @param size the number of elements in the source
   1952          * @param characteristics properties of this spliterator's
   1953          * source or elements.
   1954          */
   1955         public LongIteratorSpliterator(PrimitiveIterator.OfLong iterator, long size, int characteristics) {
   1956             this.it = iterator;
   1957             this.est = size;
   1958             this.characteristics = (characteristics & Spliterator.CONCURRENT) == 0
   1959                                    ? characteristics | Spliterator.SIZED | Spliterator.SUBSIZED
   1960                                    : characteristics;
   1961         }
   1962 
   1963         /**
   1964          * Creates a spliterator using the given iterator for a
   1965          * source of unknown size, reporting the given
   1966          * characteristics.
   1967          *
   1968          * @param iterator the iterator for the source
   1969          * @param characteristics properties of this spliterator's
   1970          * source or elements.
   1971          */
   1972         public LongIteratorSpliterator(PrimitiveIterator.OfLong iterator, int characteristics) {
   1973             this.it = iterator;
   1974             this.est = Long.MAX_VALUE;
   1975             this.characteristics = characteristics & ~(Spliterator.SIZED | Spliterator.SUBSIZED);
   1976         }
   1977 
   1978         @Override
   1979         public OfLong trySplit() {
   1980             PrimitiveIterator.OfLong i = it;
   1981             long s = est;
   1982             if (s > 1 && i.hasNext()) {
   1983                 int n = batch + BATCH_UNIT;
   1984                 if (n > s)
   1985                     n = (int) s;
   1986                 if (n > MAX_BATCH)
   1987                     n = MAX_BATCH;
   1988                 long[] a = new long[n];
   1989                 int j = 0;
   1990                 do { a[j] = i.nextLong(); } while (++j < n && i.hasNext());
   1991                 batch = j;
   1992                 if (est != Long.MAX_VALUE)
   1993                     est -= j;
   1994                 return new LongArraySpliterator(a, 0, j, characteristics);
   1995             }
   1996             return null;
   1997         }
   1998 
   1999         @Override
   2000         public void forEachRemaining(LongConsumer action) {
   2001             if (action == null) throw new NullPointerException();
   2002             it.forEachRemaining(action);
   2003         }
   2004 
   2005         @Override
   2006         public boolean tryAdvance(LongConsumer action) {
   2007             if (action == null) throw new NullPointerException();
   2008             if (it.hasNext()) {
   2009                 action.accept(it.nextLong());
   2010                 return true;
   2011             }
   2012             return false;
   2013         }
   2014 
   2015         @Override
   2016         public long estimateSize() {
   2017             return est;
   2018         }
   2019 
   2020         @Override
   2021         public int characteristics() { return characteristics; }
   2022 
   2023         @Override
   2024         public Comparator<? super Long> getComparator() {
   2025             if (hasCharacteristics(Spliterator.SORTED))
   2026                 return null;
   2027             throw new IllegalStateException();
   2028         }
   2029     }
   2030 
   2031     static final class DoubleIteratorSpliterator implements Spliterator.OfDouble {
   2032         static final int BATCH_UNIT = IteratorSpliterator.BATCH_UNIT;
   2033         static final int MAX_BATCH = IteratorSpliterator.MAX_BATCH;
   2034         private PrimitiveIterator.OfDouble it;
   2035         private final int characteristics;
   2036         private long est;             // size estimate
   2037         private int batch;            // batch size for splits
   2038 
   2039         /**
   2040          * Creates a spliterator using the given iterator
   2041          * for traversal, and reporting the given initial size
   2042          * and characteristics.
   2043          *
   2044          * @param iterator the iterator for the source
   2045          * @param size the number of elements in the source
   2046          * @param characteristics properties of this spliterator's
   2047          * source or elements.
   2048          */
   2049         public DoubleIteratorSpliterator(PrimitiveIterator.OfDouble iterator, long size, int characteristics) {
   2050             this.it = iterator;
   2051             this.est = size;
   2052             this.characteristics = (characteristics & Spliterator.CONCURRENT) == 0
   2053                                    ? characteristics | Spliterator.SIZED | Spliterator.SUBSIZED
   2054                                    : characteristics;
   2055         }
   2056 
   2057         /**
   2058          * Creates a spliterator using the given iterator for a
   2059          * source of unknown size, reporting the given
   2060          * characteristics.
   2061          *
   2062          * @param iterator the iterator for the source
   2063          * @param characteristics properties of this spliterator's
   2064          * source or elements.
   2065          */
   2066         public DoubleIteratorSpliterator(PrimitiveIterator.OfDouble iterator, int characteristics) {
   2067             this.it = iterator;
   2068             this.est = Long.MAX_VALUE;
   2069             this.characteristics = characteristics & ~(Spliterator.SIZED | Spliterator.SUBSIZED);
   2070         }
   2071 
   2072         @Override
   2073         public OfDouble trySplit() {
   2074             PrimitiveIterator.OfDouble i = it;
   2075             long s = est;
   2076             if (s > 1 && i.hasNext()) {
   2077                 int n = batch + BATCH_UNIT;
   2078                 if (n > s)
   2079                     n = (int) s;
   2080                 if (n > MAX_BATCH)
   2081                     n = MAX_BATCH;
   2082                 double[] a = new double[n];
   2083                 int j = 0;
   2084                 do { a[j] = i.nextDouble(); } while (++j < n && i.hasNext());
   2085                 batch = j;
   2086                 if (est != Long.MAX_VALUE)
   2087                     est -= j;
   2088                 return new DoubleArraySpliterator(a, 0, j, characteristics);
   2089             }
   2090             return null;
   2091         }
   2092 
   2093         @Override
   2094         public void forEachRemaining(DoubleConsumer action) {
   2095             if (action == null) throw new NullPointerException();
   2096             it.forEachRemaining(action);
   2097         }
   2098 
   2099         @Override
   2100         public boolean tryAdvance(DoubleConsumer action) {
   2101             if (action == null) throw new NullPointerException();
   2102             if (it.hasNext()) {
   2103                 action.accept(it.nextDouble());
   2104                 return true;
   2105             }
   2106             return false;
   2107         }
   2108 
   2109         @Override
   2110         public long estimateSize() {
   2111             return est;
   2112         }
   2113 
   2114         @Override
   2115         public int characteristics() { return characteristics; }
   2116 
   2117         @Override
   2118         public Comparator<? super Double> getComparator() {
   2119             if (hasCharacteristics(Spliterator.SORTED))
   2120                 return null;
   2121             throw new IllegalStateException();
   2122         }
   2123     }
   2124 }
   2125