View Javadoc
1   /*
2    * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  package java.util;
26  
27  import java.util.function.Consumer;
28  import java.util.function.DoubleConsumer;
29  import java.util.function.IntConsumer;
30  import java.util.function.LongConsumer;
31  
32  /**
33   * Static classes and methods for operating on or creating instances of
34   * {@link Spliterator} and its primitive specializations
35   * {@link Spliterator.OfInt}, {@link Spliterator.OfLong}, and
36   * {@link Spliterator.OfDouble}.
37   *
38   * @see Spliterator
39   * @since 1.8
40   */
41  public final class Spliterators {
42  
43      // Suppresses default constructor, ensuring non-instantiability.
44      private Spliterators() {}
45  
46      // Empty spliterators
47  
48      /**
49       * Creates an empty {@code Spliterator}
50       *
51       * <p>The empty spliterator reports {@link Spliterator#SIZED} and
52       * {@link Spliterator#SUBSIZED}.  Calls to
53       * {@link java.util.Spliterator#trySplit()} always return {@code null}.
54       *
55       * @param <T> Type of elements
56       * @return An empty spliterator
57       */
58      @SuppressWarnings("unchecked")
59      public static <T> Spliterator<T> emptySpliterator() {
60          return (Spliterator<T>) EMPTY_SPLITERATOR;
61      }
62  
63      private static final Spliterator<Object> EMPTY_SPLITERATOR =
64              new EmptySpliterator.OfRef<>();
65  
66      /**
67       * Creates an empty {@code Spliterator.OfInt}
68       *
69       * <p>The empty spliterator reports {@link Spliterator#SIZED} and
70       * {@link Spliterator#SUBSIZED}.  Calls to
71       * {@link java.util.Spliterator#trySplit()} always return {@code null}.
72       *
73       * @return An empty spliterator
74       */
75      public static Spliterator.OfInt emptyIntSpliterator() {
76          return EMPTY_INT_SPLITERATOR;
77      }
78  
79      private static final Spliterator.OfInt EMPTY_INT_SPLITERATOR =
80              new EmptySpliterator.OfInt();
81  
82      /**
83       * Creates an empty {@code Spliterator.OfLong}
84       *
85       * <p>The empty spliterator reports {@link Spliterator#SIZED} and
86       * {@link Spliterator#SUBSIZED}.  Calls to
87       * {@link java.util.Spliterator#trySplit()} always return {@code null}.
88       *
89       * @return An empty spliterator
90       */
91      public static Spliterator.OfLong emptyLongSpliterator() {
92          return EMPTY_LONG_SPLITERATOR;
93      }
94  
95      private static final Spliterator.OfLong EMPTY_LONG_SPLITERATOR =
96              new EmptySpliterator.OfLong();
97  
98      /**
99       * Creates an empty {@code Spliterator.OfDouble}
100      *
101      * <p>The empty spliterator reports {@link Spliterator#SIZED} and
102      * {@link Spliterator#SUBSIZED}.  Calls to
103      * {@link java.util.Spliterator#trySplit()} always return {@code null}.
104      *
105      * @return An empty spliterator
106      */
107     public static Spliterator.OfDouble emptyDoubleSpliterator() {
108         return EMPTY_DOUBLE_SPLITERATOR;
109     }
110 
111     private static final Spliterator.OfDouble EMPTY_DOUBLE_SPLITERATOR =
112             new EmptySpliterator.OfDouble();
113 
114     // Array-based spliterators
115 
116     /**
117      * Creates a {@code Spliterator} covering the elements of a given array,
118      * using a customized set of spliterator characteristics.
119      *
120      * <p>This method is provided as an implementation convenience for
121      * Spliterators which store portions of their elements in arrays, and need
122      * fine control over Spliterator characteristics.  Most other situations in
123      * which a Spliterator for an array is needed should use
124      * {@link Arrays#spliterator(Object[])}.
125      *
126      * <p>The returned spliterator always reports the characteristics
127      * {@code SIZED} and {@code SUBSIZED}.  The caller may provide additional
128      * characteristics for the spliterator to report; it is common to
129      * additionally specify {@code IMMUTABLE} and {@code ORDERED}.
130      *
131      * @param <T> Type of elements
132      * @param array The array, assumed to be unmodified during use
133      * @param additionalCharacteristics Additional spliterator characteristics
134      *        of this spliterator's source or elements beyond {@code SIZED} and
135      *        {@code SUBSIZED} which are are always reported
136      * @return A spliterator for an array
137      * @throws NullPointerException if the given array is {@code null}
138      * @see Arrays#spliterator(Object[])
139      */
140     public static <T> Spliterator<T> spliterator(Object[] array,
141                                                  int additionalCharacteristics) {
142         return new ArraySpliterator<>(Objects.requireNonNull(array),
143                                       additionalCharacteristics);
144     }
145 
146     /**
147      * Creates a {@code Spliterator} covering a range of elements of a given
148      * array, using a customized set of spliterator characteristics.
149      *
150      * <p>This method is provided as an implementation convenience for
151      * Spliterators which store portions of their elements in arrays, and need
152      * fine control over Spliterator characteristics.  Most other situations in
153      * which a Spliterator for an array is needed should use
154      * {@link Arrays#spliterator(Object[])}.
155      *
156      * <p>The returned spliterator always reports the characteristics
157      * {@code SIZED} and {@code SUBSIZED}.  The caller may provide additional
158      * characteristics for the spliterator to report; it is common to
159      * additionally specify {@code IMMUTABLE} and {@code ORDERED}.
160      *
161      * @param <T> Type of elements
162      * @param array The array, assumed to be unmodified during use
163      * @param fromIndex The least index (inclusive) to cover
164      * @param toIndex One past the greatest index to cover
165      * @param additionalCharacteristics Additional spliterator characteristics
166      *        of this spliterator's source or elements beyond {@code SIZED} and
167      *        {@code SUBSIZED} which are are always reported
168      * @return A spliterator for an array
169      * @throws NullPointerException if the given array is {@code null}
170      * @throws ArrayIndexOutOfBoundsException if {@code fromIndex} is negative,
171      *         {@code toIndex} is less than {@code fromIndex}, or
172      *         {@code toIndex} is greater than the array size
173      * @see Arrays#spliterator(Object[], int, int)
174      */
175     public static <T> Spliterator<T> spliterator(Object[] array, int fromIndex, int toIndex,
176                                                  int additionalCharacteristics) {
177         checkFromToBounds(Objects.requireNonNull(array).length, fromIndex, toIndex);
178         return new ArraySpliterator<>(array, fromIndex, toIndex, additionalCharacteristics);
179     }
180 
181     /**
182      * Creates a {@code Spliterator.OfInt} covering the elements of a given array,
183      * using a customized set of spliterator characteristics.
184      *
185      * <p>This method is provided as an implementation convenience for
186      * Spliterators which store portions of their elements in arrays, and need
187      * fine control over Spliterator characteristics.  Most other situations in
188      * which a Spliterator for an array is needed should use
189      * {@link Arrays#spliterator(int[])}.
190      *
191      * <p>The returned spliterator always reports the characteristics
192      * {@code SIZED} and {@code SUBSIZED}.  The caller may provide additional
193      * characteristics for the spliterator to report; it is common to
194      * additionally specify {@code IMMUTABLE} and {@code ORDERED}.
195      *
196      * @param array The array, assumed to be unmodified during use
197      * @param additionalCharacteristics Additional spliterator characteristics
198      *        of this spliterator's source or elements beyond {@code SIZED} and
199      *        {@code SUBSIZED} which are are always reported
200      * @return A spliterator for an array
201      * @throws NullPointerException if the given array is {@code null}
202      * @see Arrays#spliterator(int[])
203      */
204     public static Spliterator.OfInt spliterator(int[] array,
205                                                 int additionalCharacteristics) {
206         return new IntArraySpliterator(Objects.requireNonNull(array), additionalCharacteristics);
207     }
208 
209     /**
210      * Creates a {@code Spliterator.OfInt} covering a range of elements of a
211      * given array, using a customized set of spliterator characteristics.
212      *
213      * <p>This method is provided as an implementation convenience for
214      * Spliterators which store portions of their elements in arrays, and need
215      * fine control over Spliterator characteristics.  Most other situations in
216      * which a Spliterator for an array is needed should use
217      * {@link Arrays#spliterator(int[], int, int)}.
218      *
219      * <p>The returned spliterator always reports the characteristics
220      * {@code SIZED} and {@code SUBSIZED}.  The caller may provide additional
221      * characteristics for the spliterator to report; it is common to
222      * additionally specify {@code IMMUTABLE} and {@code ORDERED}.
223      *
224      * @param array The array, assumed to be unmodified during use
225      * @param fromIndex The least index (inclusive) to cover
226      * @param toIndex One past the greatest index to cover
227      * @param additionalCharacteristics Additional spliterator characteristics
228      *        of this spliterator's source or elements beyond {@code SIZED} and
229      *        {@code SUBSIZED} which are are always reported
230      * @return A spliterator for an array
231      * @throws NullPointerException if the given array is {@code null}
232      * @throws ArrayIndexOutOfBoundsException if {@code fromIndex} is negative,
233      *         {@code toIndex} is less than {@code fromIndex}, or
234      *         {@code toIndex} is greater than the array size
235      * @see Arrays#spliterator(int[], int, int)
236      */
237     public static Spliterator.OfInt spliterator(int[] array, int fromIndex, int toIndex,
238                                                 int additionalCharacteristics) {
239         checkFromToBounds(Objects.requireNonNull(array).length, fromIndex, toIndex);
240         return new IntArraySpliterator(array, fromIndex, toIndex, additionalCharacteristics);
241     }
242 
243     /**
244      * Creates a {@code Spliterator.OfLong} covering the elements of a given array,
245      * using a customized set of spliterator characteristics.
246      *
247      * <p>This method is provided as an implementation convenience for
248      * Spliterators which store portions of their elements in arrays, and need
249      * fine control over Spliterator characteristics.  Most other situations in
250      * which a Spliterator for an array is needed should use
251      * {@link Arrays#spliterator(long[])}.
252      *
253      * <p>The returned spliterator always reports the characteristics
254      * {@code SIZED} and {@code SUBSIZED}.  The caller may provide additional
255      * characteristics for the spliterator to report; it is common to
256      * additionally specify {@code IMMUTABLE} and {@code ORDERED}.
257      *
258      * @param array The array, assumed to be unmodified during use
259      * @param additionalCharacteristics Additional spliterator characteristics
260      *        of this spliterator's source or elements beyond {@code SIZED} and
261      *        {@code SUBSIZED} which are are always reported
262      * @return A spliterator for an array
263      * @throws NullPointerException if the given array is {@code null}
264      * @see Arrays#spliterator(long[])
265      */
266     public static Spliterator.OfLong spliterator(long[] array,
267                                                  int additionalCharacteristics) {
268         return new LongArraySpliterator(Objects.requireNonNull(array), additionalCharacteristics);
269     }
270 
271     /**
272      * Creates a {@code Spliterator.OfLong} covering a range of elements of a
273      * given array, using a customized set of spliterator characteristics.
274      *
275      * <p>This method is provided as an implementation convenience for
276      * Spliterators which store portions of their elements in arrays, and need
277      * fine control over Spliterator characteristics.  Most other situations in
278      * which a Spliterator for an array is needed should use
279      * {@link Arrays#spliterator(long[], int, int)}.
280      *
281      * <p>The returned spliterator always reports the characteristics
282      * {@code SIZED} and {@code SUBSIZED}.  The caller may provide additional
283      * characteristics for the spliterator to report.  (For example, if it is
284      * known the array will not be further modified, specify {@code IMMUTABLE};
285      * if the array data is considered to have an an encounter order, specify
286      * {@code ORDERED}).  The method {@link Arrays#spliterator(long[], int, int)} can
287      * often be used instead, which returns a spliterator that reports
288      * {@code SIZED}, {@code SUBSIZED}, {@code IMMUTABLE}, and {@code ORDERED}.
289      *
290      * @param array The array, assumed to be unmodified during use
291      * @param fromIndex The least index (inclusive) to cover
292      * @param toIndex One past the greatest index to cover
293      * @param additionalCharacteristics Additional spliterator characteristics
294      *        of this spliterator's source or elements beyond {@code SIZED} and
295      *        {@code SUBSIZED} which are are always reported
296      * @return A spliterator for an array
297      * @throws NullPointerException if the given array is {@code null}
298      * @throws ArrayIndexOutOfBoundsException if {@code fromIndex} is negative,
299      *         {@code toIndex} is less than {@code fromIndex}, or
300      *         {@code toIndex} is greater than the array size
301      * @see Arrays#spliterator(long[], int, int)
302      */
303     public static Spliterator.OfLong spliterator(long[] array, int fromIndex, int toIndex,
304                                                  int additionalCharacteristics) {
305         checkFromToBounds(Objects.requireNonNull(array).length, fromIndex, toIndex);
306         return new LongArraySpliterator(array, fromIndex, toIndex, additionalCharacteristics);
307     }
308 
309     /**
310      * Creates a {@code Spliterator.OfDouble} covering the elements of a given array,
311      * using a customized set of spliterator characteristics.
312      *
313      * <p>This method is provided as an implementation convenience for
314      * Spliterators which store portions of their elements in arrays, and need
315      * fine control over Spliterator characteristics.  Most other situations in
316      * which a Spliterator for an array is needed should use
317      * {@link Arrays#spliterator(double[])}.
318      *
319      * <p>The returned spliterator always reports the characteristics
320      * {@code SIZED} and {@code SUBSIZED}.  The caller may provide additional
321      * characteristics for the spliterator to report; it is common to
322      * additionally specify {@code IMMUTABLE} and {@code ORDERED}.
323      *
324      * @param array The array, assumed to be unmodified during use
325      * @param additionalCharacteristics Additional spliterator characteristics
326      *        of this spliterator's source or elements beyond {@code SIZED} and
327      *        {@code SUBSIZED} which are are always reported
328      * @return A spliterator for an array
329      * @throws NullPointerException if the given array is {@code null}
330      * @see Arrays#spliterator(double[])
331      */
332     public static Spliterator.OfDouble spliterator(double[] array,
333                                                    int additionalCharacteristics) {
334         return new DoubleArraySpliterator(Objects.requireNonNull(array), additionalCharacteristics);
335     }
336 
337     /**
338      * Creates a {@code Spliterator.OfDouble} covering a range of elements of a
339      * given array, using a customized set of spliterator characteristics.
340      *
341      * <p>This method is provided as an implementation convenience for
342      * Spliterators which store portions of their elements in arrays, and need
343      * fine control over Spliterator characteristics.  Most other situations in
344      * which a Spliterator for an array is needed should use
345      * {@link Arrays#spliterator(double[], int, int)}.
346      *
347      * <p>The returned spliterator always reports the characteristics
348      * {@code SIZED} and {@code SUBSIZED}.  The caller may provide additional
349      * characteristics for the spliterator to report.  (For example, if it is
350      * known the array will not be further modified, specify {@code IMMUTABLE};
351      * if the array data is considered to have an an encounter order, specify
352      * {@code ORDERED}).  The method {@link Arrays#spliterator(long[], int, int)} can
353      * often be used instead, which returns a spliterator that reports
354      * {@code SIZED}, {@code SUBSIZED}, {@code IMMUTABLE}, and {@code ORDERED}.
355      *
356      * @param array The array, assumed to be unmodified during use
357      * @param fromIndex The least index (inclusive) to cover
358      * @param toIndex One past the greatest index to cover
359      * @param additionalCharacteristics Additional spliterator characteristics
360      *        of this spliterator's source or elements beyond {@code SIZED} and
361      *        {@code SUBSIZED} which are are always reported
362      * @return A spliterator for an array
363      * @throws NullPointerException if the given array is {@code null}
364      * @throws ArrayIndexOutOfBoundsException if {@code fromIndex} is negative,
365      *         {@code toIndex} is less than {@code fromIndex}, or
366      *         {@code toIndex} is greater than the array size
367      * @see Arrays#spliterator(double[], int, int)
368      */
369     public static Spliterator.OfDouble spliterator(double[] array, int fromIndex, int toIndex,
370                                                    int additionalCharacteristics) {
371         checkFromToBounds(Objects.requireNonNull(array).length, fromIndex, toIndex);
372         return new DoubleArraySpliterator(array, fromIndex, toIndex, additionalCharacteristics);
373     }
374 
375     /**
376      * Validate inclusive start index and exclusive end index against the length
377      * of an array.
378      * @param arrayLength The length of the array
379      * @param origin The inclusive start index
380      * @param fence The exclusive end index
381      * @throws ArrayIndexOutOfBoundsException if the start index is greater than
382      * the end index, if the start index is negative, or the end index is
383      * greater than the array length
384      */
385     private static void checkFromToBounds(int arrayLength, int origin, int fence) {
386         if (origin > fence) {
387             throw new IllegalArgumentException(
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 }