1 /*
2  * Copyright (c) 2013, 2021, 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.
Spliterators()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")
emptySpliterator()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      */
emptyIntSpliterator()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      */
emptyLongSpliterator()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      */
emptyDoubleSpliterator()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 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      */
spliterator(Object[] array, int additionalCharacteristics)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 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      */
spliterator(Object[] array, int fromIndex, int toIndex, int additionalCharacteristics)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 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      */
spliterator(int[] array, int additionalCharacteristics)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 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      */
spliterator(int[] array, int fromIndex, int toIndex, int additionalCharacteristics)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 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      */
spliterator(long[] array, int additionalCharacteristics)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 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 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      */
spliterator(long[] array, int fromIndex, int toIndex, int additionalCharacteristics)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 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      */
spliterator(double[] array, int additionalCharacteristics)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 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 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      */
spliterator(double[] array, int fromIndex, int toIndex, int additionalCharacteristics)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      */
checkFromToBounds(int arrayLength, int origin, int fence)385     private static void checkFromToBounds(int arrayLength, int origin, int fence) {
386         if (origin > fence) {
387             throw new ArrayIndexOutOfBoundsException(
388                     "origin(" + origin + ") > fence(" + fence + ")");
389         }
390         if (origin < 0) {
391             throw new ArrayIndexOutOfBoundsException(origin);
392         }
393         if (fence > arrayLength) {
394             throw new ArrayIndexOutOfBoundsException(fence);
395         }
396     }
397 
398     // Iterator-based spliterators
399 
400     /**
401      * Creates a {@code Spliterator} using the given collection's
402      * {@link java.util.Collection#iterator()} as the source of elements, and
403      * reporting its {@link java.util.Collection#size()} as its initial size.
404      *
405      * <p>The spliterator is
406      * <em><a href="Spliterator.html#binding">late-binding</a></em>, inherits
407      * the <em>fail-fast</em> properties of the collection's iterator, and
408      * implements {@code trySplit} to permit limited parallelism.
409      *
410      * @param <T> Type of elements
411      * @param c The collection
412      * @param characteristics Characteristics of this spliterator's source or
413      *        elements.  The characteristics {@code SIZED} and {@code SUBSIZED}
414      *        are additionally reported unless {@code CONCURRENT} is supplied.
415      * @return A spliterator from an iterator
416      * @throws NullPointerException if the given collection is {@code null}
417      */
spliterator(Collection<? extends T> c, int characteristics)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      */
spliterator(Iterator<? extends T> iterator, long size, int characteristics)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      */
spliteratorUnknownSize(Iterator<? extends T> iterator, int characteristics)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      */
spliterator(PrimitiveIterator.OfInt iterator, long size, int characteristics)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      */
spliteratorUnknownSize(PrimitiveIterator.OfInt iterator, int characteristics)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      */
spliterator(PrimitiveIterator.OfLong iterator, long size, int characteristics)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      */
spliteratorUnknownSize(PrimitiveIterator.OfLong iterator, int characteristics)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      */
spliterator(PrimitiveIterator.OfDouble iterator, long size, int characteristics)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      */
spliteratorUnknownSize(PrimitiveIterator.OfDouble iterator, int characteristics)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      */
iterator(Spliterator<? extends T> spliterator)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                     T t = nextElement;
692                     nextElement = null;
693                     return t;
694                 }
695             }
696 
697             @Override
698             public void forEachRemaining(Consumer<? super T> action) {
699                 Objects.requireNonNull(action);
700                 if (valueReady) {
701                     valueReady = false;
702                     T t = nextElement;
703                     nextElement = null;
704                     action.accept(t);
705                 }
706                 spliterator.forEachRemaining(action);
707             }
708         }
709 
710         return new Adapter();
711     }
712 
713     /**
714      * Creates an {@code PrimitiveIterator.OfInt} from a
715      * {@code Spliterator.OfInt}.
716      *
717      * <p>Traversal of elements should be accomplished through the iterator.
718      * The behaviour of traversal is undefined if the spliterator is operated
719      * after the iterator is returned.
720      *
721      * @param spliterator The spliterator
722      * @return An iterator
723      * @throws NullPointerException if the given spliterator is {@code null}
724      */
iterator(Spliterator.OfInt spliterator)725     public static PrimitiveIterator.OfInt iterator(Spliterator.OfInt spliterator) {
726         Objects.requireNonNull(spliterator);
727         class Adapter implements PrimitiveIterator.OfInt, IntConsumer {
728             boolean valueReady = false;
729             int nextElement;
730 
731             @Override
732             public void accept(int t) {
733                 valueReady = true;
734                 nextElement = t;
735             }
736 
737             @Override
738             public boolean hasNext() {
739                 if (!valueReady)
740                     spliterator.tryAdvance(this);
741                 return valueReady;
742             }
743 
744             @Override
745             public int nextInt() {
746                 if (!valueReady && !hasNext())
747                     throw new NoSuchElementException();
748                 else {
749                     valueReady = false;
750                     return nextElement;
751                 }
752             }
753 
754             @Override
755             public void forEachRemaining(IntConsumer action) {
756                 Objects.requireNonNull(action);
757                 if (valueReady) {
758                     valueReady = false;
759                     action.accept(nextElement);
760                 }
761                 spliterator.forEachRemaining(action);
762             }
763         }
764 
765         return new Adapter();
766     }
767 
768     /**
769      * Creates an {@code PrimitiveIterator.OfLong} from a
770      * {@code Spliterator.OfLong}.
771      *
772      * <p>Traversal of elements should be accomplished through the iterator.
773      * The behaviour of traversal is undefined if the spliterator is operated
774      * after the iterator is returned.
775      *
776      * @param spliterator The spliterator
777      * @return An iterator
778      * @throws NullPointerException if the given spliterator is {@code null}
779      */
iterator(Spliterator.OfLong spliterator)780     public static PrimitiveIterator.OfLong iterator(Spliterator.OfLong spliterator) {
781         Objects.requireNonNull(spliterator);
782         class Adapter implements PrimitiveIterator.OfLong, LongConsumer {
783             boolean valueReady = false;
784             long nextElement;
785 
786             @Override
787             public void accept(long t) {
788                 valueReady = true;
789                 nextElement = t;
790             }
791 
792             @Override
793             public boolean hasNext() {
794                 if (!valueReady)
795                     spliterator.tryAdvance(this);
796                 return valueReady;
797             }
798 
799             @Override
800             public long nextLong() {
801                 if (!valueReady && !hasNext())
802                     throw new NoSuchElementException();
803                 else {
804                     valueReady = false;
805                     return nextElement;
806                 }
807             }
808 
809             @Override
810             public void forEachRemaining(LongConsumer action) {
811                 Objects.requireNonNull(action);
812                 if (valueReady) {
813                     valueReady = false;
814                     action.accept(nextElement);
815                 }
816                 spliterator.forEachRemaining(action);
817             }
818         }
819 
820         return new Adapter();
821     }
822 
823     /**
824      * Creates an {@code PrimitiveIterator.OfDouble} from a
825      * {@code Spliterator.OfDouble}.
826      *
827      * <p>Traversal of elements should be accomplished through the iterator.
828      * The behaviour of traversal is undefined if the spliterator is operated
829      * after the iterator is returned.
830      *
831      * @param spliterator The spliterator
832      * @return An iterator
833      * @throws NullPointerException if the given spliterator is {@code null}
834      */
iterator(Spliterator.OfDouble spliterator)835     public static PrimitiveIterator.OfDouble iterator(Spliterator.OfDouble spliterator) {
836         Objects.requireNonNull(spliterator);
837         class Adapter implements PrimitiveIterator.OfDouble, DoubleConsumer {
838             boolean valueReady = false;
839             double nextElement;
840 
841             @Override
842             public void accept(double t) {
843                 valueReady = true;
844                 nextElement = t;
845             }
846 
847             @Override
848             public boolean hasNext() {
849                 if (!valueReady)
850                     spliterator.tryAdvance(this);
851                 return valueReady;
852             }
853 
854             @Override
855             public double nextDouble() {
856                 if (!valueReady && !hasNext())
857                     throw new NoSuchElementException();
858                 else {
859                     valueReady = false;
860                     return nextElement;
861                 }
862             }
863 
864             @Override
865             public void forEachRemaining(DoubleConsumer action) {
866                 Objects.requireNonNull(action);
867                 if (valueReady) {
868                     valueReady = false;
869                     action.accept(nextElement);
870                 }
871                 spliterator.forEachRemaining(action);
872             }
873         }
874 
875         return new Adapter();
876     }
877 
878     // Implementations
879 
880     private abstract static class EmptySpliterator<T, S extends Spliterator<T>, C> {
881 
EmptySpliterator()882         EmptySpliterator() { }
883 
trySplit()884         public S trySplit() {
885             return null;
886         }
887 
tryAdvance(C consumer)888         public boolean tryAdvance(C consumer) {
889             Objects.requireNonNull(consumer);
890             return false;
891         }
892 
forEachRemaining(C consumer)893         public void forEachRemaining(C consumer) {
894             Objects.requireNonNull(consumer);
895         }
896 
estimateSize()897         public long estimateSize() {
898             return 0;
899         }
900 
characteristics()901         public int characteristics() {
902             return Spliterator.SIZED | Spliterator.SUBSIZED;
903         }
904 
905         private static final class OfRef<T>
906                 extends EmptySpliterator<T, Spliterator<T>, Consumer<? super T>>
907                 implements Spliterator<T> {
OfRef()908             OfRef() { }
909         }
910 
911         private static final class OfInt
912                 extends EmptySpliterator<Integer, Spliterator.OfInt, IntConsumer>
913                 implements Spliterator.OfInt {
OfInt()914             OfInt() { }
915         }
916 
917         private static final class OfLong
918                 extends EmptySpliterator<Long, Spliterator.OfLong, LongConsumer>
919                 implements Spliterator.OfLong {
OfLong()920             OfLong() { }
921         }
922 
923         private static final class OfDouble
924                 extends EmptySpliterator<Double, Spliterator.OfDouble, DoubleConsumer>
925                 implements Spliterator.OfDouble {
OfDouble()926             OfDouble() { }
927         }
928     }
929 
930     // Array-based spliterators
931 
932     /**
933      * A Spliterator designed for use by sources that traverse and split
934      * elements maintained in an unmodifiable {@code Object[]} array.
935      */
936     static final class ArraySpliterator<T> implements Spliterator<T> {
937         /**
938          * The array, explicitly typed as Object[]. Unlike in some other
939          * classes (see for example CR 6260652), we do not need to
940          * screen arguments to ensure they are exactly of type Object[]
941          * so long as no methods write into the array or serialize it,
942          * which we ensure here by defining this class as final.
943          */
944         private final Object[] array;
945         private int index;        // current index, modified on advance/split
946         private final int fence;  // one past last index
947         private final int characteristics;
948 
949         /**
950          * Creates a spliterator covering all of the given array.
951          * @param array the array, assumed to be unmodified during use
952          * @param additionalCharacteristics Additional spliterator characteristics
953          * of this spliterator's source or elements beyond {@code SIZED} and
954          * {@code SUBSIZED} which are always reported
955          */
ArraySpliterator(Object[] array, int additionalCharacteristics)956         public ArraySpliterator(Object[] array, int additionalCharacteristics) {
957             this(array, 0, array.length, additionalCharacteristics);
958         }
959 
960         /**
961          * Creates a spliterator covering the given array and range
962          * @param array the array, assumed to be unmodified during use
963          * @param origin the least index (inclusive) to cover
964          * @param fence one past the greatest index to cover
965          * @param additionalCharacteristics Additional spliterator characteristics
966          * of this spliterator's source or elements beyond {@code SIZED} and
967          * {@code SUBSIZED} which are always reported
968          */
ArraySpliterator(Object[] array, int origin, int fence, int additionalCharacteristics)969         public ArraySpliterator(Object[] array, int origin, int fence, int additionalCharacteristics) {
970             this.array = array;
971             this.index = origin;
972             this.fence = fence;
973             this.characteristics = additionalCharacteristics | Spliterator.SIZED | Spliterator.SUBSIZED;
974         }
975 
976         @Override
trySplit()977         public Spliterator<T> trySplit() {
978             int lo = index, mid = (lo + fence) >>> 1;
979             return (lo >= mid)
980                    ? null
981                    : new ArraySpliterator<>(array, lo, index = mid, characteristics);
982         }
983 
984         @SuppressWarnings("unchecked")
985         @Override
forEachRemaining(Consumer<? super T> action)986         public void forEachRemaining(Consumer<? super T> action) {
987             Object[] a; int i, hi; // hoist accesses and checks from loop
988             if (action == null)
989                 throw new NullPointerException();
990             if ((a = array).length >= (hi = fence) &&
991                 (i = index) >= 0 && i < (index = hi)) {
992                 do { action.accept((T)a[i]); } while (++i < hi);
993             }
994         }
995 
996         @Override
tryAdvance(Consumer<? super T> action)997         public boolean tryAdvance(Consumer<? super T> action) {
998             if (action == null)
999                 throw new NullPointerException();
1000             if (index >= 0 && index < fence) {
1001                 @SuppressWarnings("unchecked") T e = (T) array[index++];
1002                 action.accept(e);
1003                 return true;
1004             }
1005             return false;
1006         }
1007 
1008         @Override
estimateSize()1009         public long estimateSize() { return (long)(fence - index); }
1010 
1011         @Override
characteristics()1012         public int characteristics() {
1013             return characteristics;
1014         }
1015 
1016         @Override
getComparator()1017         public Comparator<? super T> getComparator() {
1018             if (hasCharacteristics(Spliterator.SORTED))
1019                 return null;
1020             throw new IllegalStateException();
1021         }
1022     }
1023 
1024     /**
1025      * A Spliterator.OfInt designed for use by sources that traverse and split
1026      * elements maintained in an unmodifiable {@code int[]} array.
1027      */
1028     static final class IntArraySpliterator implements Spliterator.OfInt {
1029         private final int[] array;
1030         private int index;        // current index, modified on advance/split
1031         private final int fence;  // one past last index
1032         private final int characteristics;
1033 
1034         /**
1035          * Creates a spliterator covering all of the given array.
1036          * @param array the array, assumed to be unmodified during use
1037          * @param additionalCharacteristics Additional spliterator characteristics
1038          *        of this spliterator's source or elements beyond {@code SIZED} and
1039          *        {@code SUBSIZED} which are always reported
1040          */
IntArraySpliterator(int[] array, int additionalCharacteristics)1041         public IntArraySpliterator(int[] array, int additionalCharacteristics) {
1042             this(array, 0, array.length, additionalCharacteristics);
1043         }
1044 
1045         /**
1046          * Creates a spliterator covering the given array and range
1047          * @param array the array, assumed to be unmodified during use
1048          * @param origin the least index (inclusive) to cover
1049          * @param fence one past the greatest index to cover
1050          * @param additionalCharacteristics Additional spliterator characteristics
1051          *        of this spliterator's source or elements beyond {@code SIZED} and
1052          *        {@code SUBSIZED} which are always reported
1053          */
IntArraySpliterator(int[] array, int origin, int fence, int additionalCharacteristics)1054         public IntArraySpliterator(int[] array, int origin, int fence, int additionalCharacteristics) {
1055             this.array = array;
1056             this.index = origin;
1057             this.fence = fence;
1058             this.characteristics = additionalCharacteristics | Spliterator.SIZED | Spliterator.SUBSIZED;
1059         }
1060 
1061         @Override
trySplit()1062         public OfInt trySplit() {
1063             int lo = index, mid = (lo + fence) >>> 1;
1064             return (lo >= mid)
1065                    ? null
1066                    : new IntArraySpliterator(array, lo, index = mid, characteristics);
1067         }
1068 
1069         @Override
forEachRemaining(IntConsumer action)1070         public void forEachRemaining(IntConsumer action) {
1071             int[] a; int i, hi; // hoist accesses and checks from loop
1072             if (action == null)
1073                 throw new NullPointerException();
1074             if ((a = array).length >= (hi = fence) &&
1075                 (i = index) >= 0 && i < (index = hi)) {
1076                 do { action.accept(a[i]); } while (++i < hi);
1077             }
1078         }
1079 
1080         @Override
tryAdvance(IntConsumer action)1081         public boolean tryAdvance(IntConsumer action) {
1082             if (action == null)
1083                 throw new NullPointerException();
1084             if (index >= 0 && index < fence) {
1085                 action.accept(array[index++]);
1086                 return true;
1087             }
1088             return false;
1089         }
1090 
1091         @Override
estimateSize()1092         public long estimateSize() { return (long)(fence - index); }
1093 
1094         @Override
characteristics()1095         public int characteristics() {
1096             return characteristics;
1097         }
1098 
1099         @Override
getComparator()1100         public Comparator<? super Integer> getComparator() {
1101             if (hasCharacteristics(Spliterator.SORTED))
1102                 return null;
1103             throw new IllegalStateException();
1104         }
1105     }
1106 
1107     /**
1108      * A Spliterator.OfLong designed for use by sources that traverse and split
1109      * elements maintained in an unmodifiable {@code int[]} array.
1110      */
1111     static final class LongArraySpliterator implements Spliterator.OfLong {
1112         private final long[] array;
1113         private int index;        // current index, modified on advance/split
1114         private final int fence;  // one past last index
1115         private final int characteristics;
1116 
1117         /**
1118          * Creates a spliterator covering all of the given array.
1119          * @param array the array, assumed to be unmodified during use
1120          * @param additionalCharacteristics Additional spliterator characteristics
1121          *        of this spliterator's source or elements beyond {@code SIZED} and
1122          *        {@code SUBSIZED} which are always reported
1123          */
LongArraySpliterator(long[] array, int additionalCharacteristics)1124         public LongArraySpliterator(long[] array, int additionalCharacteristics) {
1125             this(array, 0, array.length, additionalCharacteristics);
1126         }
1127 
1128         /**
1129          * Creates a spliterator covering the given array and range
1130          * @param array the array, assumed to be unmodified during use
1131          * @param origin the least index (inclusive) to cover
1132          * @param fence one past the greatest index to cover
1133          * @param additionalCharacteristics Additional spliterator characteristics
1134          *        of this spliterator's source or elements beyond {@code SIZED} and
1135          *        {@code SUBSIZED} which are always reported
1136          */
LongArraySpliterator(long[] array, int origin, int fence, int additionalCharacteristics)1137         public LongArraySpliterator(long[] array, int origin, int fence, int additionalCharacteristics) {
1138             this.array = array;
1139             this.index = origin;
1140             this.fence = fence;
1141             this.characteristics = additionalCharacteristics | Spliterator.SIZED | Spliterator.SUBSIZED;
1142         }
1143 
1144         @Override
trySplit()1145         public OfLong trySplit() {
1146             int lo = index, mid = (lo + fence) >>> 1;
1147             return (lo >= mid)
1148                    ? null
1149                    : new LongArraySpliterator(array, lo, index = mid, characteristics);
1150         }
1151 
1152         @Override
forEachRemaining(LongConsumer action)1153         public void forEachRemaining(LongConsumer action) {
1154             long[] a; int i, hi; // hoist accesses and checks from loop
1155             if (action == null)
1156                 throw new NullPointerException();
1157             if ((a = array).length >= (hi = fence) &&
1158                 (i = index) >= 0 && i < (index = hi)) {
1159                 do { action.accept(a[i]); } while (++i < hi);
1160             }
1161         }
1162 
1163         @Override
tryAdvance(LongConsumer action)1164         public boolean tryAdvance(LongConsumer action) {
1165             if (action == null)
1166                 throw new NullPointerException();
1167             if (index >= 0 && index < fence) {
1168                 action.accept(array[index++]);
1169                 return true;
1170             }
1171             return false;
1172         }
1173 
1174         @Override
estimateSize()1175         public long estimateSize() { return (long)(fence - index); }
1176 
1177         @Override
characteristics()1178         public int characteristics() {
1179             return characteristics;
1180         }
1181 
1182         @Override
getComparator()1183         public Comparator<? super Long> getComparator() {
1184             if (hasCharacteristics(Spliterator.SORTED))
1185                 return null;
1186             throw new IllegalStateException();
1187         }
1188     }
1189 
1190     /**
1191      * A Spliterator.OfDouble designed for use by sources that traverse and split
1192      * elements maintained in an unmodifiable {@code int[]} array.
1193      */
1194     static final class DoubleArraySpliterator implements Spliterator.OfDouble {
1195         private final double[] array;
1196         private int index;        // current index, modified on advance/split
1197         private final int fence;  // one past last index
1198         private final int characteristics;
1199 
1200         /**
1201          * Creates a spliterator covering all of the given array.
1202          * @param array the array, assumed to be unmodified during use
1203          * @param additionalCharacteristics Additional spliterator characteristics
1204          *        of this spliterator's source or elements beyond {@code SIZED} and
1205          *        {@code SUBSIZED} which are always reported
1206          */
DoubleArraySpliterator(double[] array, int additionalCharacteristics)1207         public DoubleArraySpliterator(double[] array, int additionalCharacteristics) {
1208             this(array, 0, array.length, additionalCharacteristics);
1209         }
1210 
1211         /**
1212          * Creates a spliterator covering the given array and range
1213          * @param array the array, assumed to be unmodified during use
1214          * @param origin the least index (inclusive) to cover
1215          * @param fence one past the greatest index to cover
1216          * @param additionalCharacteristics Additional spliterator characteristics
1217          *        of this spliterator's source or elements beyond {@code SIZED} and
1218          *        {@code SUBSIZED} which are always reported
1219          */
DoubleArraySpliterator(double[] array, int origin, int fence, int additionalCharacteristics)1220         public DoubleArraySpliterator(double[] array, int origin, int fence, int additionalCharacteristics) {
1221             this.array = array;
1222             this.index = origin;
1223             this.fence = fence;
1224             this.characteristics = additionalCharacteristics | Spliterator.SIZED | Spliterator.SUBSIZED;
1225         }
1226 
1227         @Override
trySplit()1228         public OfDouble trySplit() {
1229             int lo = index, mid = (lo + fence) >>> 1;
1230             return (lo >= mid)
1231                    ? null
1232                    : new DoubleArraySpliterator(array, lo, index = mid, characteristics);
1233         }
1234 
1235         @Override
forEachRemaining(DoubleConsumer action)1236         public void forEachRemaining(DoubleConsumer action) {
1237             double[] a; int i, hi; // hoist accesses and checks from loop
1238             if (action == null)
1239                 throw new NullPointerException();
1240             if ((a = array).length >= (hi = fence) &&
1241                 (i = index) >= 0 && i < (index = hi)) {
1242                 do { action.accept(a[i]); } while (++i < hi);
1243             }
1244         }
1245 
1246         @Override
tryAdvance(DoubleConsumer action)1247         public boolean tryAdvance(DoubleConsumer action) {
1248             if (action == null)
1249                 throw new NullPointerException();
1250             if (index >= 0 && index < fence) {
1251                 action.accept(array[index++]);
1252                 return true;
1253             }
1254             return false;
1255         }
1256 
1257         @Override
estimateSize()1258         public long estimateSize() { return (long)(fence - index); }
1259 
1260         @Override
characteristics()1261         public int characteristics() {
1262             return characteristics;
1263         }
1264 
1265         @Override
getComparator()1266         public Comparator<? super Double> getComparator() {
1267             if (hasCharacteristics(Spliterator.SORTED))
1268                 return null;
1269             throw new IllegalStateException();
1270         }
1271     }
1272 
1273     //
1274 
1275     /**
1276      * An abstract {@code Spliterator} that implements {@code trySplit} to
1277      * permit limited parallelism.
1278      *
1279      * <p>An extending class need only
1280      * implement {@link #tryAdvance(java.util.function.Consumer) tryAdvance}.
1281      * The extending class should override
1282      * {@link #forEachRemaining(java.util.function.Consumer) forEachRemaining}
1283      * if it can provide a more performant implementation.
1284      *
1285      * @apiNote
1286      * This class is a useful aid for creating a spliterator when it is not
1287      * possible or difficult to efficiently partition elements in a manner
1288      * allowing balanced parallel computation.
1289      *
1290      * <p>An alternative to using this class, that also permits limited
1291      * parallelism, is to create a spliterator from an iterator
1292      * (see {@link #spliterator(Iterator, long, int)}.  Depending on the
1293      * circumstances using an iterator may be easier or more convenient than
1294      * extending this class, such as when there is already an iterator
1295      * available to use.
1296      *
1297      * @see #spliterator(Iterator, long, int)
1298      * @since 1.8
1299      */
1300     public abstract static class AbstractSpliterator<T> implements Spliterator<T> {
1301         static final int BATCH_UNIT = 1 << 10;  // batch array size increment
1302         static final int MAX_BATCH = 1 << 25;  // max batch array size;
1303         private final int characteristics;
1304         private long est;             // size estimate
1305         private int batch;            // batch size for splits
1306 
1307         /**
1308          * Creates a spliterator reporting the given estimated size and
1309          * additionalCharacteristics.
1310          *
1311          * @param est the estimated size of this spliterator if known, otherwise
1312          *        {@code Long.MAX_VALUE}.
1313          * @param additionalCharacteristics properties of this spliterator's
1314          *        source or elements.  If {@code SIZED} is reported then this
1315          *        spliterator will additionally report {@code SUBSIZED}.
1316          */
AbstractSpliterator(long est, int additionalCharacteristics)1317         protected AbstractSpliterator(long est, int additionalCharacteristics) {
1318             this.est = est;
1319             this.characteristics = ((additionalCharacteristics & Spliterator.SIZED) != 0)
1320                                    ? additionalCharacteristics | Spliterator.SUBSIZED
1321                                    : additionalCharacteristics;
1322         }
1323 
1324         static final class HoldingConsumer<T> implements Consumer<T> {
1325             Object value;
1326 
1327             @Override
accept(T value)1328             public void accept(T value) {
1329                 this.value = value;
1330             }
1331         }
1332 
1333         /**
1334          * {@inheritDoc}
1335          *
1336          * This implementation permits limited parallelism.
1337          */
1338         @Override
trySplit()1339         public Spliterator<T> trySplit() {
1340             /*
1341              * Split into arrays of arithmetically increasing batch
1342              * sizes.  This will only improve parallel performance if
1343              * per-element Consumer actions are more costly than
1344              * transferring them into an array.  The use of an
1345              * arithmetic progression in split sizes provides overhead
1346              * vs parallelism bounds that do not particularly favor or
1347              * penalize cases of lightweight vs heavyweight element
1348              * operations, across combinations of #elements vs #cores,
1349              * whether or not either are known.  We generate
1350              * O(sqrt(#elements)) splits, allowing O(sqrt(#cores))
1351              * potential speedup.
1352              */
1353             HoldingConsumer<T> holder = new HoldingConsumer<>();
1354             long s = est;
1355             if (s > 1 && tryAdvance(holder)) {
1356                 int n = batch + BATCH_UNIT;
1357                 if (n > s)
1358                     n = (int) s;
1359                 if (n > MAX_BATCH)
1360                     n = MAX_BATCH;
1361                 Object[] a = new Object[n];
1362                 int j = 0;
1363                 do { a[j] = holder.value; } while (++j < n && tryAdvance(holder));
1364                 batch = j;
1365                 if (est != Long.MAX_VALUE)
1366                     est -= j;
1367                 return new ArraySpliterator<>(a, 0, j, characteristics());
1368             }
1369             return null;
1370         }
1371 
1372         /**
1373          * {@inheritDoc}
1374          *
1375          * @implSpec
1376          * This implementation returns the estimated size as reported when
1377          * created and, if the estimate size is known, decreases in size when
1378          * split.
1379          */
1380         @Override
estimateSize()1381         public long estimateSize() {
1382             return est;
1383         }
1384 
1385         /**
1386          * {@inheritDoc}
1387          *
1388          * @implSpec
1389          * This implementation returns the characteristics as reported when
1390          * created.
1391          */
1392         @Override
characteristics()1393         public int characteristics() {
1394             return characteristics;
1395         }
1396     }
1397 
1398     /**
1399      * An abstract {@code Spliterator.OfInt} that implements {@code trySplit} to
1400      * permit limited parallelism.
1401      *
1402      * <p>To implement a spliterator an extending class need only
1403      * implement {@link #tryAdvance(java.util.function.IntConsumer)
1404      * tryAdvance}.  The extending class should override
1405      * {@link #forEachRemaining(java.util.function.IntConsumer) forEachRemaining}
1406      * if it can provide a more performant implementation.
1407      *
1408      * @apiNote
1409      * This class is a useful aid for creating a spliterator when it is not
1410      * possible or difficult to efficiently partition elements in a manner
1411      * allowing balanced parallel computation.
1412      *
1413      * <p>An alternative to using this class, that also permits limited
1414      * parallelism, is to create a spliterator from an iterator
1415      * (see {@link #spliterator(java.util.PrimitiveIterator.OfInt, long, int)}.
1416      * Depending on the circumstances using an iterator may be easier or more
1417      * convenient than extending this class. For example, if there is already an
1418      * iterator available to use then there is no need to extend this class.
1419      *
1420      * @see #spliterator(java.util.PrimitiveIterator.OfInt, long, int)
1421      * @since 1.8
1422      */
1423     public abstract static class AbstractIntSpliterator implements Spliterator.OfInt {
1424         static final int MAX_BATCH = AbstractSpliterator.MAX_BATCH;
1425         static final int BATCH_UNIT = AbstractSpliterator.BATCH_UNIT;
1426         private final int characteristics;
1427         private long est;             // size estimate
1428         private int batch;            // batch size for splits
1429 
1430         /**
1431          * Creates a spliterator reporting the given estimated size and
1432          * characteristics.
1433          *
1434          * @param est the estimated size of this spliterator if known, otherwise
1435          *        {@code Long.MAX_VALUE}.
1436          * @param additionalCharacteristics properties of this spliterator's
1437          *        source or elements.  If {@code SIZED} is reported then this
1438          *        spliterator will additionally report {@code SUBSIZED}.
1439          */
AbstractIntSpliterator(long est, int additionalCharacteristics)1440         protected AbstractIntSpliterator(long est, int additionalCharacteristics) {
1441             this.est = est;
1442             this.characteristics = ((additionalCharacteristics & Spliterator.SIZED) != 0)
1443                                    ? additionalCharacteristics | Spliterator.SUBSIZED
1444                                    : additionalCharacteristics;
1445         }
1446 
1447         static final class HoldingIntConsumer implements IntConsumer {
1448             int value;
1449 
1450             @Override
accept(int value)1451             public void accept(int value) {
1452                 this.value = value;
1453             }
1454         }
1455 
1456         /**
1457          * {@inheritDoc}
1458          *
1459          * This implementation permits limited parallelism.
1460          */
1461         @Override
trySplit()1462         public Spliterator.OfInt trySplit() {
1463             HoldingIntConsumer holder = new HoldingIntConsumer();
1464             long s = est;
1465             if (s > 1 && tryAdvance(holder)) {
1466                 int n = batch + BATCH_UNIT;
1467                 if (n > s)
1468                     n = (int) s;
1469                 if (n > MAX_BATCH)
1470                     n = MAX_BATCH;
1471                 int[] a = new int[n];
1472                 int j = 0;
1473                 do { a[j] = holder.value; } while (++j < n && tryAdvance(holder));
1474                 batch = j;
1475                 if (est != Long.MAX_VALUE)
1476                     est -= j;
1477                 return new IntArraySpliterator(a, 0, j, characteristics());
1478             }
1479             return null;
1480         }
1481 
1482         /**
1483          * {@inheritDoc}
1484          *
1485          * @implSpec
1486          * This implementation returns the estimated size as reported when
1487          * created and, if the estimate size is known, decreases in size when
1488          * split.
1489          */
1490         @Override
estimateSize()1491         public long estimateSize() {
1492             return est;
1493         }
1494 
1495         /**
1496          * {@inheritDoc}
1497          *
1498          * @implSpec
1499          * This implementation returns the characteristics as reported when
1500          * created.
1501          */
1502         @Override
characteristics()1503         public int characteristics() {
1504             return characteristics;
1505         }
1506     }
1507 
1508     /**
1509      * An abstract {@code Spliterator.OfLong} that implements {@code trySplit}
1510      * to permit limited parallelism.
1511      *
1512      * <p>To implement a spliterator an extending class need only
1513      * implement {@link #tryAdvance(java.util.function.LongConsumer)
1514      * tryAdvance}.  The extending class should override
1515      * {@link #forEachRemaining(java.util.function.LongConsumer) forEachRemaining}
1516      * if it can provide a more performant implementation.
1517      *
1518      * @apiNote
1519      * This class is a useful aid for creating a spliterator when it is not
1520      * possible or difficult to efficiently partition elements in a manner
1521      * allowing balanced parallel computation.
1522      *
1523      * <p>An alternative to using this class, that also permits limited
1524      * parallelism, is to create a spliterator from an iterator
1525      * (see {@link #spliterator(java.util.PrimitiveIterator.OfLong, long, int)}.
1526      * Depending on the circumstances using an iterator may be easier or more
1527      * convenient than extending this class. For example, if there is already an
1528      * iterator available to use then there is no need to extend this class.
1529      *
1530      * @see #spliterator(java.util.PrimitiveIterator.OfLong, long, int)
1531      * @since 1.8
1532      */
1533     public abstract static class AbstractLongSpliterator implements Spliterator.OfLong {
1534         static final int MAX_BATCH = AbstractSpliterator.MAX_BATCH;
1535         static final int BATCH_UNIT = AbstractSpliterator.BATCH_UNIT;
1536         private final int characteristics;
1537         private long est;             // size estimate
1538         private int batch;            // batch size for splits
1539 
1540         /**
1541          * Creates a spliterator reporting the given estimated size and
1542          * characteristics.
1543          *
1544          * @param est the estimated size of this spliterator if known, otherwise
1545          *        {@code Long.MAX_VALUE}.
1546          * @param additionalCharacteristics properties of this spliterator's
1547          *        source or elements.  If {@code SIZED} is reported then this
1548          *        spliterator will additionally report {@code SUBSIZED}.
1549          */
AbstractLongSpliterator(long est, int additionalCharacteristics)1550         protected AbstractLongSpliterator(long est, int additionalCharacteristics) {
1551             this.est = est;
1552             this.characteristics = ((additionalCharacteristics & Spliterator.SIZED) != 0)
1553                                    ? additionalCharacteristics | Spliterator.SUBSIZED
1554                                    : additionalCharacteristics;
1555         }
1556 
1557         static final class HoldingLongConsumer implements LongConsumer {
1558             long value;
1559 
1560             @Override
accept(long value)1561             public void accept(long value) {
1562                 this.value = value;
1563             }
1564         }
1565 
1566         /**
1567          * {@inheritDoc}
1568          *
1569          * This implementation permits limited parallelism.
1570          */
1571         @Override
trySplit()1572         public Spliterator.OfLong trySplit() {
1573             HoldingLongConsumer holder = new HoldingLongConsumer();
1574             long s = est;
1575             if (s > 1 && tryAdvance(holder)) {
1576                 int n = batch + BATCH_UNIT;
1577                 if (n > s)
1578                     n = (int) s;
1579                 if (n > MAX_BATCH)
1580                     n = MAX_BATCH;
1581                 long[] a = new long[n];
1582                 int j = 0;
1583                 do { a[j] = holder.value; } while (++j < n && tryAdvance(holder));
1584                 batch = j;
1585                 if (est != Long.MAX_VALUE)
1586                     est -= j;
1587                 return new LongArraySpliterator(a, 0, j, characteristics());
1588             }
1589             return null;
1590         }
1591 
1592         /**
1593          * {@inheritDoc}
1594          *
1595          * @implSpec
1596          * This implementation returns the estimated size as reported when
1597          * created and, if the estimate size is known, decreases in size when
1598          * split.
1599          */
1600         @Override
estimateSize()1601         public long estimateSize() {
1602             return est;
1603         }
1604 
1605         /**
1606          * {@inheritDoc}
1607          *
1608          * @implSpec
1609          * This implementation returns the characteristics as reported when
1610          * created.
1611          */
1612         @Override
characteristics()1613         public int characteristics() {
1614             return characteristics;
1615         }
1616     }
1617 
1618     /**
1619      * An abstract {@code Spliterator.OfDouble} that implements
1620      * {@code trySplit} to permit limited parallelism.
1621      *
1622      * <p>To implement a spliterator an extending class need only
1623      * implement {@link #tryAdvance(java.util.function.DoubleConsumer)
1624      * tryAdvance}.  The extending class should override
1625      * {@link #forEachRemaining(java.util.function.DoubleConsumer) forEachRemaining}
1626      * if it can provide a more performant implementation.
1627      *
1628      * @apiNote
1629      * This class is a useful aid for creating a spliterator when it is not
1630      * possible or difficult to efficiently partition elements in a manner
1631      * allowing balanced parallel computation.
1632      *
1633      * <p>An alternative to using this class, that also permits limited
1634      * parallelism, is to create a spliterator from an iterator
1635      * (see {@link #spliterator(java.util.PrimitiveIterator.OfDouble, long, int)}.
1636      * Depending on the circumstances using an iterator may be easier or more
1637      * convenient than extending this class. For example, if there is already an
1638      * iterator available to use then there is no need to extend this class.
1639      *
1640      * @see #spliterator(java.util.PrimitiveIterator.OfDouble, long, int)
1641      * @since 1.8
1642      */
1643     public abstract static class AbstractDoubleSpliterator implements Spliterator.OfDouble {
1644         static final int MAX_BATCH = AbstractSpliterator.MAX_BATCH;
1645         static final int BATCH_UNIT = AbstractSpliterator.BATCH_UNIT;
1646         private final int characteristics;
1647         private long est;             // size estimate
1648         private int batch;            // batch size for splits
1649 
1650         /**
1651          * Creates a spliterator reporting the given estimated size and
1652          * characteristics.
1653          *
1654          * @param est the estimated size of this spliterator if known, otherwise
1655          *        {@code Long.MAX_VALUE}.
1656          * @param additionalCharacteristics properties of this spliterator's
1657          *        source or elements.  If {@code SIZED} is reported then this
1658          *        spliterator will additionally report {@code SUBSIZED}.
1659          */
AbstractDoubleSpliterator(long est, int additionalCharacteristics)1660         protected AbstractDoubleSpliterator(long est, int additionalCharacteristics) {
1661             this.est = est;
1662             this.characteristics = ((additionalCharacteristics & Spliterator.SIZED) != 0)
1663                                    ? additionalCharacteristics | Spliterator.SUBSIZED
1664                                    : additionalCharacteristics;
1665         }
1666 
1667         static final class HoldingDoubleConsumer implements DoubleConsumer {
1668             double value;
1669 
1670             @Override
accept(double value)1671             public void accept(double value) {
1672                 this.value = value;
1673             }
1674         }
1675 
1676         /**
1677          * {@inheritDoc}
1678          *
1679          * This implementation permits limited parallelism.
1680          */
1681         @Override
trySplit()1682         public Spliterator.OfDouble trySplit() {
1683             HoldingDoubleConsumer holder = new HoldingDoubleConsumer();
1684             long s = est;
1685             if (s > 1 && tryAdvance(holder)) {
1686                 int n = batch + BATCH_UNIT;
1687                 if (n > s)
1688                     n = (int) s;
1689                 if (n > MAX_BATCH)
1690                     n = MAX_BATCH;
1691                 double[] a = new double[n];
1692                 int j = 0;
1693                 do { a[j] = holder.value; } while (++j < n && tryAdvance(holder));
1694                 batch = j;
1695                 if (est != Long.MAX_VALUE)
1696                     est -= j;
1697                 return new DoubleArraySpliterator(a, 0, j, characteristics());
1698             }
1699             return null;
1700         }
1701 
1702         /**
1703          * {@inheritDoc}
1704          *
1705          * @implSpec
1706          * This implementation returns the estimated size as reported when
1707          * created and, if the estimate size is known, decreases in size when
1708          * split.
1709          */
1710         @Override
estimateSize()1711         public long estimateSize() {
1712             return est;
1713         }
1714 
1715         /**
1716          * {@inheritDoc}
1717          *
1718          * @implSpec
1719          * This implementation returns the characteristics as reported when
1720          * created.
1721          */
1722         @Override
characteristics()1723         public int characteristics() {
1724             return characteristics;
1725         }
1726     }
1727 
1728     // Iterator-based Spliterators
1729 
1730     /**
1731      * A Spliterator using a given Iterator for element
1732      * operations. The spliterator implements {@code trySplit} to
1733      * permit limited parallelism.
1734      */
1735     static class IteratorSpliterator<T> implements Spliterator<T> {
1736         static final int BATCH_UNIT = 1 << 10;  // batch array size increment
1737         static final int MAX_BATCH = 1 << 25;  // max batch array size;
1738         private final Collection<? extends T> collection; // null OK
1739         private Iterator<? extends T> it;
1740         private final int characteristics;
1741         private long est;             // size estimate
1742         private int batch;            // batch size for splits
1743 
1744         /**
1745          * Creates a spliterator using the given
1746          * collection's {@link java.util.Collection#iterator()) for traversal,
1747          * and reporting its {@link java.util.Collection#size()) as its initial
1748          * size.
1749          *
1750          * @param c the collection
1751          * @param characteristics properties of this spliterator's
1752          *        source or elements.
1753          */
IteratorSpliterator(Collection<? extends T> collection, int characteristics)1754         public IteratorSpliterator(Collection<? extends T> collection, int characteristics) {
1755             this.collection = collection;
1756             this.it = null;
1757             this.characteristics = (characteristics & Spliterator.CONCURRENT) == 0
1758                                    ? characteristics | Spliterator.SIZED | Spliterator.SUBSIZED
1759                                    : characteristics;
1760         }
1761 
1762         /**
1763          * Creates a spliterator using the given iterator
1764          * for traversal, and reporting the given initial size
1765          * and characteristics.
1766          *
1767          * @param iterator the iterator for the source
1768          * @param size the number of elements in the source
1769          * @param characteristics properties of this spliterator's
1770          * source or elements.
1771          */
IteratorSpliterator(Iterator<? extends T> iterator, long size, int characteristics)1772         public IteratorSpliterator(Iterator<? extends T> iterator, long size, int characteristics) {
1773             this.collection = null;
1774             this.it = iterator;
1775             this.est = size;
1776             this.characteristics = (characteristics & Spliterator.CONCURRENT) == 0
1777                                    ? characteristics | Spliterator.SIZED | Spliterator.SUBSIZED
1778                                    : characteristics;
1779         }
1780 
1781         /**
1782          * Creates a spliterator using the given iterator
1783          * for traversal, and reporting the given initial size
1784          * and characteristics.
1785          *
1786          * @param iterator the iterator for the source
1787          * @param characteristics properties of this spliterator's
1788          * source or elements.
1789          */
IteratorSpliterator(Iterator<? extends T> iterator, int characteristics)1790         public IteratorSpliterator(Iterator<? extends T> iterator, int characteristics) {
1791             this.collection = null;
1792             this.it = iterator;
1793             this.est = Long.MAX_VALUE;
1794             this.characteristics = characteristics & ~(Spliterator.SIZED | Spliterator.SUBSIZED);
1795         }
1796 
1797         @Override
trySplit()1798         public Spliterator<T> trySplit() {
1799             /*
1800              * Split into arrays of arithmetically increasing batch
1801              * sizes.  This will only improve parallel performance if
1802              * per-element Consumer actions are more costly than
1803              * transferring them into an array.  The use of an
1804              * arithmetic progression in split sizes provides overhead
1805              * vs parallelism bounds that do not particularly favor or
1806              * penalize cases of lightweight vs heavyweight element
1807              * operations, across combinations of #elements vs #cores,
1808              * whether or not either are known.  We generate
1809              * O(sqrt(#elements)) splits, allowing O(sqrt(#cores))
1810              * potential speedup.
1811              */
1812             Iterator<? extends T> i;
1813             long s;
1814             if ((i = it) == null) {
1815                 i = it = collection.iterator();
1816                 s = est = (long) collection.size();
1817             }
1818             else
1819                 s = est;
1820             if (s > 1 && i.hasNext()) {
1821                 int n = batch + BATCH_UNIT;
1822                 if (n > s)
1823                     n = (int) s;
1824                 if (n > MAX_BATCH)
1825                     n = MAX_BATCH;
1826                 Object[] a = new Object[n];
1827                 int j = 0;
1828                 do { a[j] = i.next(); } while (++j < n && i.hasNext());
1829                 batch = j;
1830                 if (est != Long.MAX_VALUE)
1831                     est -= j;
1832                 return new ArraySpliterator<>(a, 0, j, characteristics);
1833             }
1834             return null;
1835         }
1836 
1837         @Override
forEachRemaining(Consumer<? super T> action)1838         public void forEachRemaining(Consumer<? super T> action) {
1839             if (action == null) throw new NullPointerException();
1840             Iterator<? extends T> i;
1841             if ((i = it) == null) {
1842                 i = it = collection.iterator();
1843                 est = (long)collection.size();
1844             }
1845             i.forEachRemaining(action);
1846         }
1847 
1848         @Override
tryAdvance(Consumer<? super T> action)1849         public boolean tryAdvance(Consumer<? super T> action) {
1850             if (action == null) throw new NullPointerException();
1851             if (it == null) {
1852                 it = collection.iterator();
1853                 est = (long) collection.size();
1854             }
1855             if (it.hasNext()) {
1856                 action.accept(it.next());
1857                 return true;
1858             }
1859             return false;
1860         }
1861 
1862         @Override
estimateSize()1863         public long estimateSize() {
1864             if (it == null) {
1865                 it = collection.iterator();
1866                 return est = (long)collection.size();
1867             }
1868             return est;
1869         }
1870 
1871         @Override
characteristics()1872         public int characteristics() { return characteristics; }
1873 
1874         @Override
getComparator()1875         public Comparator<? super T> getComparator() {
1876             if (hasCharacteristics(Spliterator.SORTED))
1877                 return null;
1878             throw new IllegalStateException();
1879         }
1880     }
1881 
1882     /**
1883      * A Spliterator.OfInt using a given IntStream.IntIterator for element
1884      * operations. The spliterator implements {@code trySplit} to
1885      * permit limited parallelism.
1886      */
1887     static final class IntIteratorSpliterator implements Spliterator.OfInt {
1888         static final int BATCH_UNIT = IteratorSpliterator.BATCH_UNIT;
1889         static final int MAX_BATCH = IteratorSpliterator.MAX_BATCH;
1890         private final PrimitiveIterator.OfInt it;
1891         private final int characteristics;
1892         private long est;             // size estimate
1893         private int batch;            // batch size for splits
1894 
1895         /**
1896          * Creates a spliterator using the given iterator
1897          * for traversal, and reporting the given initial size
1898          * and characteristics.
1899          *
1900          * @param iterator the iterator for the source
1901          * @param size the number of elements in the source
1902          * @param characteristics properties of this spliterator's
1903          * source or elements.
1904          */
IntIteratorSpliterator(PrimitiveIterator.OfInt iterator, long size, int characteristics)1905         public IntIteratorSpliterator(PrimitiveIterator.OfInt iterator, long size, int characteristics) {
1906             this.it = iterator;
1907             this.est = size;
1908             this.characteristics = (characteristics & Spliterator.CONCURRENT) == 0
1909                                    ? characteristics | Spliterator.SIZED | Spliterator.SUBSIZED
1910                                    : characteristics;
1911         }
1912 
1913         /**
1914          * Creates a spliterator using the given iterator for a
1915          * source of unknown size, reporting the given
1916          * characteristics.
1917          *
1918          * @param iterator the iterator for the source
1919          * @param characteristics properties of this spliterator's
1920          * source or elements.
1921          */
IntIteratorSpliterator(PrimitiveIterator.OfInt iterator, int characteristics)1922         public IntIteratorSpliterator(PrimitiveIterator.OfInt iterator, int characteristics) {
1923             this.it = iterator;
1924             this.est = Long.MAX_VALUE;
1925             this.characteristics = characteristics & ~(Spliterator.SIZED | Spliterator.SUBSIZED);
1926         }
1927 
1928         @Override
trySplit()1929         public OfInt trySplit() {
1930             PrimitiveIterator.OfInt i = it;
1931             long s = est;
1932             if (s > 1 && i.hasNext()) {
1933                 int n = batch + BATCH_UNIT;
1934                 if (n > s)
1935                     n = (int) s;
1936                 if (n > MAX_BATCH)
1937                     n = MAX_BATCH;
1938                 int[] a = new int[n];
1939                 int j = 0;
1940                 do { a[j] = i.nextInt(); } while (++j < n && i.hasNext());
1941                 batch = j;
1942                 if (est != Long.MAX_VALUE)
1943                     est -= j;
1944                 return new IntArraySpliterator(a, 0, j, characteristics);
1945             }
1946             return null;
1947         }
1948 
1949         @Override
forEachRemaining(IntConsumer action)1950         public void forEachRemaining(IntConsumer action) {
1951             if (action == null) throw new NullPointerException();
1952             it.forEachRemaining(action);
1953         }
1954 
1955         @Override
tryAdvance(IntConsumer action)1956         public boolean tryAdvance(IntConsumer action) {
1957             if (action == null) throw new NullPointerException();
1958             if (it.hasNext()) {
1959                 action.accept(it.nextInt());
1960                 return true;
1961             }
1962             return false;
1963         }
1964 
1965         @Override
estimateSize()1966         public long estimateSize() {
1967             return est;
1968         }
1969 
1970         @Override
characteristics()1971         public int characteristics() { return characteristics; }
1972 
1973         @Override
getComparator()1974         public Comparator<? super Integer> getComparator() {
1975             if (hasCharacteristics(Spliterator.SORTED))
1976                 return null;
1977             throw new IllegalStateException();
1978         }
1979     }
1980 
1981     static final class LongIteratorSpliterator implements Spliterator.OfLong {
1982         static final int BATCH_UNIT = IteratorSpliterator.BATCH_UNIT;
1983         static final int MAX_BATCH = IteratorSpliterator.MAX_BATCH;
1984         private final PrimitiveIterator.OfLong it;
1985         private final int characteristics;
1986         private long est;             // size estimate
1987         private int batch;            // batch size for splits
1988 
1989         /**
1990          * Creates a spliterator using the given iterator
1991          * for traversal, and reporting the given initial size
1992          * and characteristics.
1993          *
1994          * @param iterator the iterator for the source
1995          * @param size the number of elements in the source
1996          * @param characteristics properties of this spliterator's
1997          * source or elements.
1998          */
LongIteratorSpliterator(PrimitiveIterator.OfLong iterator, long size, int characteristics)1999         public LongIteratorSpliterator(PrimitiveIterator.OfLong iterator, long size, int characteristics) {
2000             this.it = iterator;
2001             this.est = size;
2002             this.characteristics = (characteristics & Spliterator.CONCURRENT) == 0
2003                                    ? characteristics | Spliterator.SIZED | Spliterator.SUBSIZED
2004                                    : characteristics;
2005         }
2006 
2007         /**
2008          * Creates a spliterator using the given iterator for a
2009          * source of unknown size, reporting the given
2010          * characteristics.
2011          *
2012          * @param iterator the iterator for the source
2013          * @param characteristics properties of this spliterator's
2014          * source or elements.
2015          */
LongIteratorSpliterator(PrimitiveIterator.OfLong iterator, int characteristics)2016         public LongIteratorSpliterator(PrimitiveIterator.OfLong iterator, int characteristics) {
2017             this.it = iterator;
2018             this.est = Long.MAX_VALUE;
2019             this.characteristics = characteristics & ~(Spliterator.SIZED | Spliterator.SUBSIZED);
2020         }
2021 
2022         @Override
trySplit()2023         public OfLong trySplit() {
2024             PrimitiveIterator.OfLong i = it;
2025             long s = est;
2026             if (s > 1 && i.hasNext()) {
2027                 int n = batch + BATCH_UNIT;
2028                 if (n > s)
2029                     n = (int) s;
2030                 if (n > MAX_BATCH)
2031                     n = MAX_BATCH;
2032                 long[] a = new long[n];
2033                 int j = 0;
2034                 do { a[j] = i.nextLong(); } while (++j < n && i.hasNext());
2035                 batch = j;
2036                 if (est != Long.MAX_VALUE)
2037                     est -= j;
2038                 return new LongArraySpliterator(a, 0, j, characteristics);
2039             }
2040             return null;
2041         }
2042 
2043         @Override
forEachRemaining(LongConsumer action)2044         public void forEachRemaining(LongConsumer action) {
2045             if (action == null) throw new NullPointerException();
2046             it.forEachRemaining(action);
2047         }
2048 
2049         @Override
tryAdvance(LongConsumer action)2050         public boolean tryAdvance(LongConsumer action) {
2051             if (action == null) throw new NullPointerException();
2052             if (it.hasNext()) {
2053                 action.accept(it.nextLong());
2054                 return true;
2055             }
2056             return false;
2057         }
2058 
2059         @Override
estimateSize()2060         public long estimateSize() {
2061             return est;
2062         }
2063 
2064         @Override
characteristics()2065         public int characteristics() { return characteristics; }
2066 
2067         @Override
getComparator()2068         public Comparator<? super Long> getComparator() {
2069             if (hasCharacteristics(Spliterator.SORTED))
2070                 return null;
2071             throw new IllegalStateException();
2072         }
2073     }
2074 
2075     static final class DoubleIteratorSpliterator implements Spliterator.OfDouble {
2076         static final int BATCH_UNIT = IteratorSpliterator.BATCH_UNIT;
2077         static final int MAX_BATCH = IteratorSpliterator.MAX_BATCH;
2078         private final PrimitiveIterator.OfDouble it;
2079         private final int characteristics;
2080         private long est;             // size estimate
2081         private int batch;            // batch size for splits
2082 
2083         /**
2084          * Creates a spliterator using the given iterator
2085          * for traversal, and reporting the given initial size
2086          * and characteristics.
2087          *
2088          * @param iterator the iterator for the source
2089          * @param size the number of elements in the source
2090          * @param characteristics properties of this spliterator's
2091          * source or elements.
2092          */
DoubleIteratorSpliterator(PrimitiveIterator.OfDouble iterator, long size, int characteristics)2093         public DoubleIteratorSpliterator(PrimitiveIterator.OfDouble iterator, long size, int characteristics) {
2094             this.it = iterator;
2095             this.est = size;
2096             this.characteristics = (characteristics & Spliterator.CONCURRENT) == 0
2097                                    ? characteristics | Spliterator.SIZED | Spliterator.SUBSIZED
2098                                    : characteristics;
2099         }
2100 
2101         /**
2102          * Creates a spliterator using the given iterator for a
2103          * source of unknown size, reporting the given
2104          * characteristics.
2105          *
2106          * @param iterator the iterator for the source
2107          * @param characteristics properties of this spliterator's
2108          * source or elements.
2109          */
DoubleIteratorSpliterator(PrimitiveIterator.OfDouble iterator, int characteristics)2110         public DoubleIteratorSpliterator(PrimitiveIterator.OfDouble iterator, int characteristics) {
2111             this.it = iterator;
2112             this.est = Long.MAX_VALUE;
2113             this.characteristics = characteristics & ~(Spliterator.SIZED | Spliterator.SUBSIZED);
2114         }
2115 
2116         @Override
trySplit()2117         public OfDouble trySplit() {
2118             PrimitiveIterator.OfDouble i = it;
2119             long s = est;
2120             if (s > 1 && i.hasNext()) {
2121                 int n = batch + BATCH_UNIT;
2122                 if (n > s)
2123                     n = (int) s;
2124                 if (n > MAX_BATCH)
2125                     n = MAX_BATCH;
2126                 double[] a = new double[n];
2127                 int j = 0;
2128                 do { a[j] = i.nextDouble(); } while (++j < n && i.hasNext());
2129                 batch = j;
2130                 if (est != Long.MAX_VALUE)
2131                     est -= j;
2132                 return new DoubleArraySpliterator(a, 0, j, characteristics);
2133             }
2134             return null;
2135         }
2136 
2137         @Override
forEachRemaining(DoubleConsumer action)2138         public void forEachRemaining(DoubleConsumer action) {
2139             if (action == null) throw new NullPointerException();
2140             it.forEachRemaining(action);
2141         }
2142 
2143         @Override
tryAdvance(DoubleConsumer action)2144         public boolean tryAdvance(DoubleConsumer action) {
2145             if (action == null) throw new NullPointerException();
2146             if (it.hasNext()) {
2147                 action.accept(it.nextDouble());
2148                 return true;
2149             }
2150             return false;
2151         }
2152 
2153         @Override
estimateSize()2154         public long estimateSize() {
2155             return est;
2156         }
2157 
2158         @Override
characteristics()2159         public int characteristics() { return characteristics; }
2160 
2161         @Override
getComparator()2162         public Comparator<? super Double> getComparator() {
2163             if (hasCharacteristics(Spliterator.SORTED))
2164                 return null;
2165             throw new IllegalStateException();
2166         }
2167     }
2168 }
2169