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 */
25package java.util;
26
27import java.util.function.Consumer;
28import java.util.function.DoubleConsumer;
29import java.util.function.IntConsumer;
30import 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 */
41public 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