• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013, 2023, 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() iterator} as the source of elements, and
403      * reporting its {@link java.util.Collection#size() 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         @SuppressWarnings("overloads")
912         private static final class OfInt
913                 extends EmptySpliterator<Integer, Spliterator.OfInt, IntConsumer>
914                 implements Spliterator.OfInt {
OfInt()915             OfInt() { }
916         }
917 
918         @SuppressWarnings("overloads")
919         private static final class OfLong
920                 extends EmptySpliterator<Long, Spliterator.OfLong, LongConsumer>
921                 implements Spliterator.OfLong {
OfLong()922             OfLong() { }
923         }
924 
925         @SuppressWarnings("overloads")
926         private static final class OfDouble
927                 extends EmptySpliterator<Double, Spliterator.OfDouble, DoubleConsumer>
928                 implements Spliterator.OfDouble {
OfDouble()929             OfDouble() { }
930         }
931     }
932 
933     // Array-based spliterators
934 
935     /**
936      * A Spliterator designed for use by sources that traverse and split
937      * elements maintained in an unmodifiable {@code Object[]} array.
938      */
939     static final class ArraySpliterator<T> implements Spliterator<T> {
940         /**
941          * The array, explicitly typed as Object[]. Unlike in some other
942          * classes (see for example CR 6260652), we do not need to
943          * screen arguments to ensure they are exactly of type Object[]
944          * so long as no methods write into the array or serialize it,
945          * which we ensure here by defining this class as final.
946          */
947         private final Object[] array;
948         private int index;        // current index, modified on advance/split
949         private final int fence;  // one past last index
950         private final int characteristics;
951         private long estimatedSize; // if >= 0, the estimated size, to help to split evenly
952                                     // if -1, exact size is known to be fence - index
953 
954         /**
955          * Creates a spliterator covering all of the given array.
956          * Its size is known exactly and it is SIZED and SUBSIZED.
957          * @param array the array, assumed to be unmodified during use
958          * @param additionalCharacteristics Additional spliterator characteristics
959          * of this spliterator's source or elements beyond {@code SIZED} and
960          * {@code SUBSIZED} which are always reported
961          */
ArraySpliterator(Object[] array, int additionalCharacteristics)962         public ArraySpliterator(Object[] array, int additionalCharacteristics) {
963             this(array, 0, array.length, additionalCharacteristics);
964         }
965 
966         /**
967          * Creates a spliterator covering the given array and range.
968          * Its size is known exactly and it is SIZED and SUBSIZED.
969          * @param array the array, assumed to be unmodified during use
970          * @param origin the least index (inclusive) to cover
971          * @param fence one past the greatest index to cover
972          * @param additionalCharacteristics Additional spliterator characteristics
973          * of this spliterator's source or elements beyond {@code SIZED} and
974          * {@code SUBSIZED} which are always reported
975          */
ArraySpliterator(Object[] array, int origin, int fence, int additionalCharacteristics)976         public ArraySpliterator(Object[] array, int origin, int fence, int additionalCharacteristics) {
977             this.array = array;
978             this.index = origin;
979             this.fence = fence;
980             this.characteristics = additionalCharacteristics | Spliterator.SIZED | Spliterator.SUBSIZED;
981             this.estimatedSize = -1;
982         }
983 
984         /**
985          * Creates a spliterator covering the given array and range but that is
986          * not SIZED or SUBSIZED. This case occurs as a result of splitting another
987          * spliterator that is not sized, so it's inappropriate for one of its
988          * sub-spliterators to be sized.
989          * @param array the array, assumed to be unmodified during use
990          * @param origin the least index (inclusive) to cover
991          * @param fence one past the greatest index to cover
992          * @param characteristics characteristics of this spliterator's source; {@code SIZED} and
993          *        {@code SUBSIZED} are removed if present
994          * @param estimatedSize the size estimate; should always be nonnegative
995          */
ArraySpliterator(Object[] array, int origin, int fence, int characteristics, long estimatedSize)996         private ArraySpliterator(Object[] array, int origin, int fence, int characteristics, long estimatedSize) {
997             this.array = array;
998             this.index = origin;
999             this.fence = fence;
1000             this.characteristics = characteristics & ~(Spliterator.SIZED | Spliterator.SUBSIZED);
1001             this.estimatedSize = estimatedSize;
1002         }
1003 
1004         @Override
trySplit()1005         public Spliterator<T> trySplit() {
1006             int lo = index, mid = (lo + fence) >>> 1;
1007             if (lo >= mid) return null;
1008             if (estimatedSize == -1) {
1009                 return new ArraySpliterator<>(array, lo, index = mid, characteristics);
1010             }
1011             long prefixEstimatedSize = estimatedSize >>> 1;
1012             estimatedSize -= prefixEstimatedSize;
1013             return new ArraySpliterator<>(array, lo, index = mid, characteristics, prefixEstimatedSize);
1014         }
1015 
1016         @SuppressWarnings("unchecked")
1017         @Override
forEachRemaining(Consumer<? super T> action)1018         public void forEachRemaining(Consumer<? super T> action) {
1019             Object[] a; int i, hi; // hoist accesses and checks from loop
1020             if (action == null)
1021                 throw new NullPointerException();
1022             if ((a = array).length >= (hi = fence) &&
1023                 (i = index) >= 0 && i < (index = hi)) {
1024                 do { action.accept((T)a[i]); } while (++i < hi);
1025             }
1026         }
1027 
1028         @Override
tryAdvance(Consumer<? super T> action)1029         public boolean tryAdvance(Consumer<? super T> action) {
1030             if (action == null)
1031                 throw new NullPointerException();
1032             if (index >= 0 && index < fence) {
1033                 @SuppressWarnings("unchecked") T e = (T) array[index++];
1034                 action.accept(e);
1035                 return true;
1036             }
1037             return false;
1038         }
1039 
1040         @Override
estimateSize()1041         public long estimateSize() {
1042             return estimatedSize >= 0 ? estimatedSize : (long)(fence - index);
1043         }
1044 
1045         @Override
characteristics()1046         public int characteristics() {
1047             return characteristics;
1048         }
1049 
1050         @Override
getComparator()1051         public Comparator<? super T> getComparator() {
1052             if (hasCharacteristics(Spliterator.SORTED))
1053                 return null;
1054             throw new IllegalStateException();
1055         }
1056     }
1057 
1058     /**
1059      * A Spliterator.OfInt designed for use by sources that traverse and split
1060      * elements maintained in an unmodifiable {@code int[]} array.
1061      */
1062     static final class IntArraySpliterator implements Spliterator.OfInt {
1063         private final int[] array;
1064         private int index;        // current index, modified on advance/split
1065         private final int fence;  // one past last index
1066         private final int characteristics;
1067         private long estimatedSize; // estimated size, to help to split evenly
1068 
1069         /**
1070          * Creates a spliterator covering all of the given array.
1071          * @param array the array, assumed to be unmodified during use
1072          * @param additionalCharacteristics Additional spliterator characteristics
1073          *        of this spliterator's source or elements beyond {@code SIZED} and
1074          *        {@code SUBSIZED} which are always reported
1075          */
IntArraySpliterator(int[] array, int additionalCharacteristics)1076         public IntArraySpliterator(int[] array, int additionalCharacteristics) {
1077             this(array, 0, array.length, additionalCharacteristics);
1078         }
1079 
1080         /**
1081          * Creates a spliterator covering the given array and range
1082          * @param array the array, assumed to be unmodified during use
1083          * @param origin the least index (inclusive) to cover
1084          * @param fence one past the greatest index to cover
1085          * @param additionalCharacteristics Additional spliterator characteristics
1086          *        of this spliterator's source or elements beyond {@code SIZED} and
1087          *        {@code SUBSIZED} which are always reported
1088          */
IntArraySpliterator(int[] array, int origin, int fence, int additionalCharacteristics)1089         public IntArraySpliterator(int[] array, int origin, int fence, int additionalCharacteristics) {
1090             this.array = array;
1091             this.index = origin;
1092             this.fence = fence;
1093             this.characteristics = additionalCharacteristics | Spliterator.SIZED | Spliterator.SUBSIZED;
1094             this.estimatedSize = -1;
1095         }
1096 
IntArraySpliterator(int[] array, int origin, int fence, int characteristics, long estimatedSize)1097         private IntArraySpliterator(int[] array, int origin, int fence, int characteristics, long estimatedSize) {
1098             this.array = array;
1099             this.index = origin;
1100             this.fence = fence;
1101             this.characteristics = characteristics & ~(Spliterator.SIZED | Spliterator.SUBSIZED);
1102             this.estimatedSize = estimatedSize;
1103         }
1104 
1105         @Override
trySplit()1106         public OfInt trySplit() {
1107             int lo = index, mid = (lo + fence) >>> 1;
1108             if (lo >= mid) return null;
1109             if (estimatedSize == -1) {
1110                 return new IntArraySpliterator(array, lo, index = mid, characteristics);
1111             }
1112             long prefixEstimatedSize = estimatedSize >>> 1;
1113             estimatedSize -= prefixEstimatedSize;
1114             return new IntArraySpliterator(array, lo, index = mid, characteristics, prefixEstimatedSize);
1115         }
1116 
1117         @Override
forEachRemaining(IntConsumer action)1118         public void forEachRemaining(IntConsumer action) {
1119             int[] a; int i, hi; // hoist accesses and checks from loop
1120             if (action == null)
1121                 throw new NullPointerException();
1122             if ((a = array).length >= (hi = fence) &&
1123                 (i = index) >= 0 && i < (index = hi)) {
1124                 do { action.accept(a[i]); } while (++i < hi);
1125             }
1126         }
1127 
1128         @Override
tryAdvance(IntConsumer action)1129         public boolean tryAdvance(IntConsumer action) {
1130             if (action == null)
1131                 throw new NullPointerException();
1132             if (index >= 0 && index < fence) {
1133                 action.accept(array[index++]);
1134                 return true;
1135             }
1136             return false;
1137         }
1138 
1139         @Override
estimateSize()1140         public long estimateSize() {
1141             return estimatedSize >= 0 ? estimatedSize : (long)(fence - index);
1142         }
1143 
1144         @Override
characteristics()1145         public int characteristics() {
1146             return characteristics;
1147         }
1148 
1149         @Override
getComparator()1150         public Comparator<? super Integer> getComparator() {
1151             if (hasCharacteristics(Spliterator.SORTED))
1152                 return null;
1153             throw new IllegalStateException();
1154         }
1155     }
1156 
1157     /**
1158      * A Spliterator.OfLong designed for use by sources that traverse and split
1159      * elements maintained in an unmodifiable {@code int[]} array.
1160      */
1161     static final class LongArraySpliterator implements Spliterator.OfLong {
1162         private final long[] array;
1163         private int index;        // current index, modified on advance/split
1164         private final int fence;  // one past last index
1165         private final int characteristics;
1166         private long estimatedSize; // estimated size, to help to split evenly
1167 
1168         /**
1169          * Creates a spliterator covering all of the given array.
1170          * @param array the array, assumed to be unmodified during use
1171          * @param additionalCharacteristics Additional spliterator characteristics
1172          *        of this spliterator's source or elements beyond {@code SIZED} and
1173          *        {@code SUBSIZED} which are always reported
1174          */
LongArraySpliterator(long[] array, int additionalCharacteristics)1175         public LongArraySpliterator(long[] array, int additionalCharacteristics) {
1176             this(array, 0, array.length, additionalCharacteristics);
1177         }
1178 
1179         /**
1180          * Creates a spliterator covering the given array and range
1181          * @param array the array, assumed to be unmodified during use
1182          * @param origin the least index (inclusive) to cover
1183          * @param fence one past the greatest index to cover
1184          * @param additionalCharacteristics Additional spliterator characteristics
1185          *        of this spliterator's source or elements beyond {@code SIZED} and
1186          *        {@code SUBSIZED} which are always reported
1187          */
LongArraySpliterator(long[] array, int origin, int fence, int additionalCharacteristics)1188         public LongArraySpliterator(long[] array, int origin, int fence, int additionalCharacteristics) {
1189             this.array = array;
1190             this.index = origin;
1191             this.fence = fence;
1192             this.characteristics = additionalCharacteristics | Spliterator.SIZED | Spliterator.SUBSIZED;
1193             this.estimatedSize = -1;
1194         }
1195 
LongArraySpliterator(long[] array, int origin, int fence, int characteristics, long estimatedSize)1196         private LongArraySpliterator(long[] array, int origin, int fence, int characteristics, long estimatedSize) {
1197             this.array = array;
1198             this.index = origin;
1199             this.fence = fence;
1200             this.characteristics = characteristics & ~(Spliterator.SIZED | Spliterator.SUBSIZED);
1201             this.estimatedSize = estimatedSize;
1202         }
1203 
1204         @Override
trySplit()1205         public OfLong trySplit() {
1206             int lo = index, mid = (lo + fence) >>> 1;
1207             if (lo >= mid) return null;
1208             if (estimatedSize == -1) {
1209                 return new LongArraySpliterator(array, lo, index = mid, characteristics);
1210             }
1211             long prefixEstimatedSize = estimatedSize >>> 1;
1212             estimatedSize -= prefixEstimatedSize;
1213             return new LongArraySpliterator(array, lo, index = mid, characteristics, prefixEstimatedSize);
1214         }
1215 
1216         @Override
forEachRemaining(LongConsumer action)1217         public void forEachRemaining(LongConsumer action) {
1218             long[] a; int i, hi; // hoist accesses and checks from loop
1219             if (action == null)
1220                 throw new NullPointerException();
1221             if ((a = array).length >= (hi = fence) &&
1222                 (i = index) >= 0 && i < (index = hi)) {
1223                 do { action.accept(a[i]); } while (++i < hi);
1224             }
1225         }
1226 
1227         @Override
tryAdvance(LongConsumer action)1228         public boolean tryAdvance(LongConsumer action) {
1229             if (action == null)
1230                 throw new NullPointerException();
1231             if (index >= 0 && index < fence) {
1232                 action.accept(array[index++]);
1233                 return true;
1234             }
1235             return false;
1236         }
1237 
1238         @Override
estimateSize()1239         public long estimateSize() {
1240             return estimatedSize >= 0 ? estimatedSize : (long)(fence - index);
1241         }
1242 
1243         @Override
characteristics()1244         public int characteristics() {
1245             return characteristics;
1246         }
1247 
1248         @Override
getComparator()1249         public Comparator<? super Long> getComparator() {
1250             if (hasCharacteristics(Spliterator.SORTED))
1251                 return null;
1252             throw new IllegalStateException();
1253         }
1254     }
1255 
1256     /**
1257      * A Spliterator.OfDouble designed for use by sources that traverse and split
1258      * elements maintained in an unmodifiable {@code int[]} array.
1259      */
1260     static final class DoubleArraySpliterator implements Spliterator.OfDouble {
1261         private final double[] array;
1262         private int index;        // current index, modified on advance/split
1263         private final int fence;  // one past last index
1264         private final int characteristics;
1265         private long estimatedSize; // estimated size, to help to split evenly
1266 
1267         /**
1268          * Creates a spliterator covering all of the given array.
1269          * @param array the array, assumed to be unmodified during use
1270          * @param additionalCharacteristics Additional spliterator characteristics
1271          *        of this spliterator's source or elements beyond {@code SIZED} and
1272          *        {@code SUBSIZED} which are always reported
1273          */
DoubleArraySpliterator(double[] array, int additionalCharacteristics)1274         public DoubleArraySpliterator(double[] array, int additionalCharacteristics) {
1275             this(array, 0, array.length, additionalCharacteristics);
1276         }
1277 
1278         /**
1279          * Creates a spliterator covering the given array and range
1280          * @param array the array, assumed to be unmodified during use
1281          * @param origin the least index (inclusive) to cover
1282          * @param fence one past the greatest index to cover
1283          * @param additionalCharacteristics Additional spliterator characteristics
1284          *        of this spliterator's source or elements beyond {@code SIZED} and
1285          *        {@code SUBSIZED} which are always reported
1286          */
DoubleArraySpliterator(double[] array, int origin, int fence, int additionalCharacteristics)1287         public DoubleArraySpliterator(double[] array, int origin, int fence, int additionalCharacteristics) {
1288             this.array = array;
1289             this.index = origin;
1290             this.fence = fence;
1291             this.characteristics = additionalCharacteristics | Spliterator.SIZED | Spliterator.SUBSIZED;
1292             this.estimatedSize = -1;
1293         }
1294 
DoubleArraySpliterator(double[] array, int origin, int fence, int characteristics, long estimatedSize)1295         private DoubleArraySpliterator(double[] array, int origin, int fence, int characteristics, long estimatedSize) {
1296             this.array = array;
1297             this.index = origin;
1298             this.fence = fence;
1299             this.characteristics = characteristics & ~(Spliterator.SIZED | Spliterator.SUBSIZED);
1300             this.estimatedSize = estimatedSize;
1301         }
1302 
1303         @Override
trySplit()1304         public OfDouble trySplit() {
1305             int lo = index, mid = (lo + fence) >>> 1;
1306             if (lo >= mid) return null;
1307             if (estimatedSize == -1) {
1308                 return new DoubleArraySpliterator(array, lo, index = mid, characteristics);
1309             }
1310             long prefixEstimatedSize = estimatedSize >>> 1;
1311             estimatedSize -= prefixEstimatedSize;
1312             return new DoubleArraySpliterator(array, lo, index = mid, characteristics, prefixEstimatedSize);
1313         }
1314 
1315         @Override
forEachRemaining(DoubleConsumer action)1316         public void forEachRemaining(DoubleConsumer action) {
1317             double[] a; int i, hi; // hoist accesses and checks from loop
1318             if (action == null)
1319                 throw new NullPointerException();
1320             if ((a = array).length >= (hi = fence) &&
1321                 (i = index) >= 0 && i < (index = hi)) {
1322                 do { action.accept(a[i]); } while (++i < hi);
1323             }
1324         }
1325 
1326         @Override
tryAdvance(DoubleConsumer action)1327         public boolean tryAdvance(DoubleConsumer action) {
1328             if (action == null)
1329                 throw new NullPointerException();
1330             if (index >= 0 && index < fence) {
1331                 action.accept(array[index++]);
1332                 return true;
1333             }
1334             return false;
1335         }
1336 
1337         @Override
estimateSize()1338         public long estimateSize() {
1339             return estimatedSize >= 0 ? estimatedSize : (long)(fence - index);
1340         }
1341 
1342         @Override
characteristics()1343         public int characteristics() {
1344             return characteristics;
1345         }
1346 
1347         @Override
getComparator()1348         public Comparator<? super Double> getComparator() {
1349             if (hasCharacteristics(Spliterator.SORTED))
1350                 return null;
1351             throw new IllegalStateException();
1352         }
1353     }
1354 
1355     //
1356 
1357     /**
1358      * An abstract {@code Spliterator} that implements {@code trySplit} to
1359      * permit limited parallelism.
1360      *
1361      * <p>An extending class need only
1362      * implement {@link #tryAdvance(java.util.function.Consumer) tryAdvance}.
1363      * The extending class should override
1364      * {@link #forEachRemaining(java.util.function.Consumer) forEachRemaining}
1365      * if it can provide a more performant implementation.
1366      *
1367      * @apiNote
1368      * This class is a useful aid for creating a spliterator when it is not
1369      * possible or difficult to efficiently partition elements in a manner
1370      * allowing balanced parallel computation.
1371      *
1372      * <p>An alternative to using this class, that also permits limited
1373      * parallelism, is to create a spliterator from an iterator
1374      * (see {@link #spliterator(Iterator, long, int)}.  Depending on the
1375      * circumstances using an iterator may be easier or more convenient than
1376      * extending this class, such as when there is already an iterator
1377      * available to use.
1378      *
1379      * @param <T> the type of elements returned by this Spliterator
1380      *
1381      * @see #spliterator(Iterator, long, int)
1382      * @since 1.8
1383      */
1384     public abstract static class AbstractSpliterator<T> implements Spliterator<T> {
1385         static final int BATCH_UNIT = 1 << 10;  // batch array size increment
1386         static final int MAX_BATCH = 1 << 25;  // max batch array size;
1387         private final int characteristics;
1388         private long est;             // size estimate
1389         private int batch;            // batch size for splits
1390 
1391         /**
1392          * Creates a spliterator reporting the given estimated size and
1393          * additionalCharacteristics.
1394          *
1395          * @param est the estimated size of this spliterator if known, otherwise
1396          *        {@code Long.MAX_VALUE}.
1397          * @param additionalCharacteristics properties of this spliterator's
1398          *        source or elements.  If {@code SIZED} is reported then this
1399          *        spliterator will additionally report {@code SUBSIZED}.
1400          */
AbstractSpliterator(long est, int additionalCharacteristics)1401         protected AbstractSpliterator(long est, int additionalCharacteristics) {
1402             this.est = est;
1403             this.characteristics = ((additionalCharacteristics & Spliterator.SIZED) != 0)
1404                                    ? additionalCharacteristics | Spliterator.SUBSIZED
1405                                    : additionalCharacteristics;
1406         }
1407 
1408         static final class HoldingConsumer<T> implements Consumer<T> {
1409             Object value;
1410 
1411             @Override
accept(T value)1412             public void accept(T value) {
1413                 this.value = value;
1414             }
1415         }
1416 
1417         /**
1418          * {@inheritDoc}
1419          *
1420          * This implementation permits limited parallelism.
1421          */
1422         @Override
trySplit()1423         public Spliterator<T> trySplit() {
1424             /*
1425              * Split into arrays of arithmetically increasing batch
1426              * sizes.  This will only improve parallel performance if
1427              * per-element Consumer actions are more costly than
1428              * transferring them into an array.  The use of an
1429              * arithmetic progression in split sizes provides overhead
1430              * vs parallelism bounds that do not particularly favor or
1431              * penalize cases of lightweight vs heavyweight element
1432              * operations, across combinations of #elements vs #cores,
1433              * whether or not either are known.  We generate
1434              * O(sqrt(#elements)) splits, allowing O(sqrt(#cores))
1435              * potential speedup.
1436              */
1437             HoldingConsumer<T> holder = new HoldingConsumer<>();
1438             long s = est;
1439             if (s > 1 && tryAdvance(holder)) {
1440                 int n = batch + BATCH_UNIT;
1441                 if (n > s)
1442                     n = (int) s;
1443                 if (n > MAX_BATCH)
1444                     n = MAX_BATCH;
1445                 Object[] a = new Object[n];
1446                 int j = 0;
1447                 do { a[j] = holder.value; } while (++j < n && tryAdvance(holder));
1448                 batch = j;
1449                 if (est != Long.MAX_VALUE) {
1450                     est -= j;
1451                     return new ArraySpliterator<>(a, 0, j, characteristics);
1452                 }
1453                 return new ArraySpliterator<>(a, 0, j, characteristics, Long.MAX_VALUE / 2);
1454             }
1455             return null;
1456         }
1457 
1458         /**
1459          * {@inheritDoc}
1460          *
1461          * @implSpec
1462          * This implementation returns the estimated size as reported when
1463          * created and, if the estimate size is known, decreases in size when
1464          * split.
1465          */
1466         @Override
estimateSize()1467         public long estimateSize() {
1468             return est;
1469         }
1470 
1471         /**
1472          * {@inheritDoc}
1473          *
1474          * @implSpec
1475          * This implementation returns the characteristics as reported when
1476          * created.
1477          */
1478         @Override
characteristics()1479         public int characteristics() {
1480             return characteristics;
1481         }
1482     }
1483 
1484     /**
1485      * An abstract {@code Spliterator.OfInt} that implements {@code trySplit} to
1486      * permit limited parallelism.
1487      *
1488      * <p>To implement a spliterator an extending class need only
1489      * implement {@link #tryAdvance(java.util.function.IntConsumer)
1490      * tryAdvance}.  The extending class should override
1491      * {@link #forEachRemaining(java.util.function.IntConsumer) forEachRemaining}
1492      * if it can provide a more performant implementation.
1493      *
1494      * @apiNote
1495      * This class is a useful aid for creating a spliterator when it is not
1496      * possible or difficult to efficiently partition elements in a manner
1497      * allowing balanced parallel computation.
1498      *
1499      * <p>An alternative to using this class, that also permits limited
1500      * parallelism, is to create a spliterator from an iterator
1501      * (see {@link #spliterator(java.util.PrimitiveIterator.OfInt, long, int)}.
1502      * Depending on the circumstances using an iterator may be easier or more
1503      * convenient than extending this class. For example, if there is already an
1504      * iterator available to use then there is no need to extend this class.
1505      *
1506      * @see #spliterator(java.util.PrimitiveIterator.OfInt, long, int)
1507      * @since 1.8
1508      */
1509     public abstract static class AbstractIntSpliterator implements Spliterator.OfInt {
1510         static final int MAX_BATCH = AbstractSpliterator.MAX_BATCH;
1511         static final int BATCH_UNIT = AbstractSpliterator.BATCH_UNIT;
1512         private final int characteristics;
1513         private long est;             // size estimate
1514         private int batch;            // batch size for splits
1515 
1516         /**
1517          * Creates a spliterator reporting the given estimated size and
1518          * characteristics.
1519          *
1520          * @param est the estimated size of this spliterator if known, otherwise
1521          *        {@code Long.MAX_VALUE}.
1522          * @param additionalCharacteristics properties of this spliterator's
1523          *        source or elements.  If {@code SIZED} is reported then this
1524          *        spliterator will additionally report {@code SUBSIZED}.
1525          */
AbstractIntSpliterator(long est, int additionalCharacteristics)1526         protected AbstractIntSpliterator(long est, int additionalCharacteristics) {
1527             this.est = est;
1528             this.characteristics = ((additionalCharacteristics & Spliterator.SIZED) != 0)
1529                                    ? additionalCharacteristics | Spliterator.SUBSIZED
1530                                    : additionalCharacteristics;
1531         }
1532 
1533         static final class HoldingIntConsumer implements IntConsumer {
1534             int value;
1535 
1536             @Override
accept(int value)1537             public void accept(int value) {
1538                 this.value = value;
1539             }
1540         }
1541 
1542         /**
1543          * {@inheritDoc}
1544          *
1545          * This implementation permits limited parallelism.
1546          */
1547         @Override
trySplit()1548         public Spliterator.OfInt trySplit() {
1549             HoldingIntConsumer holder = new HoldingIntConsumer();
1550             long s = est;
1551             if (s > 1 && tryAdvance(holder)) {
1552                 int n = batch + BATCH_UNIT;
1553                 if (n > s)
1554                     n = (int) s;
1555                 if (n > MAX_BATCH)
1556                     n = MAX_BATCH;
1557                 int[] a = new int[n];
1558                 int j = 0;
1559                 do { a[j] = holder.value; } while (++j < n && tryAdvance(holder));
1560                 batch = j;
1561                 if (est != Long.MAX_VALUE) {
1562                     est -= j;
1563                     return new IntArraySpliterator(a, 0, j, characteristics);
1564                 }
1565                 return new IntArraySpliterator(a, 0, j, characteristics, Long.MAX_VALUE / 2);
1566             }
1567             return null;
1568         }
1569 
1570         /**
1571          * {@inheritDoc}
1572          *
1573          * @implSpec
1574          * This implementation returns the estimated size as reported when
1575          * created and, if the estimate size is known, decreases in size when
1576          * split.
1577          */
1578         @Override
estimateSize()1579         public long estimateSize() {
1580             return est;
1581         }
1582 
1583         /**
1584          * {@inheritDoc}
1585          *
1586          * @implSpec
1587          * This implementation returns the characteristics as reported when
1588          * created.
1589          */
1590         @Override
characteristics()1591         public int characteristics() {
1592             return characteristics;
1593         }
1594     }
1595 
1596     /**
1597      * An abstract {@code Spliterator.OfLong} that implements {@code trySplit}
1598      * to permit limited parallelism.
1599      *
1600      * <p>To implement a spliterator an extending class need only
1601      * implement {@link #tryAdvance(java.util.function.LongConsumer)
1602      * tryAdvance}.  The extending class should override
1603      * {@link #forEachRemaining(java.util.function.LongConsumer) forEachRemaining}
1604      * if it can provide a more performant implementation.
1605      *
1606      * @apiNote
1607      * This class is a useful aid for creating a spliterator when it is not
1608      * possible or difficult to efficiently partition elements in a manner
1609      * allowing balanced parallel computation.
1610      *
1611      * <p>An alternative to using this class, that also permits limited
1612      * parallelism, is to create a spliterator from an iterator
1613      * (see {@link #spliterator(java.util.PrimitiveIterator.OfLong, long, int)}.
1614      * Depending on the circumstances using an iterator may be easier or more
1615      * convenient than extending this class. For example, if there is already an
1616      * iterator available to use then there is no need to extend this class.
1617      *
1618      * @see #spliterator(java.util.PrimitiveIterator.OfLong, long, int)
1619      * @since 1.8
1620      */
1621     public abstract static class AbstractLongSpliterator implements Spliterator.OfLong {
1622         static final int MAX_BATCH = AbstractSpliterator.MAX_BATCH;
1623         static final int BATCH_UNIT = AbstractSpliterator.BATCH_UNIT;
1624         private final int characteristics;
1625         private long est;             // size estimate
1626         private int batch;            // batch size for splits
1627 
1628         /**
1629          * Creates a spliterator reporting the given estimated size and
1630          * characteristics.
1631          *
1632          * @param est the estimated size of this spliterator if known, otherwise
1633          *        {@code Long.MAX_VALUE}.
1634          * @param additionalCharacteristics properties of this spliterator's
1635          *        source or elements.  If {@code SIZED} is reported then this
1636          *        spliterator will additionally report {@code SUBSIZED}.
1637          */
AbstractLongSpliterator(long est, int additionalCharacteristics)1638         protected AbstractLongSpliterator(long est, int additionalCharacteristics) {
1639             this.est = est;
1640             this.characteristics = ((additionalCharacteristics & Spliterator.SIZED) != 0)
1641                                    ? additionalCharacteristics | Spliterator.SUBSIZED
1642                                    : additionalCharacteristics;
1643         }
1644 
1645         static final class HoldingLongConsumer implements LongConsumer {
1646             long value;
1647 
1648             @Override
accept(long value)1649             public void accept(long value) {
1650                 this.value = value;
1651             }
1652         }
1653 
1654         /**
1655          * {@inheritDoc}
1656          *
1657          * This implementation permits limited parallelism.
1658          */
1659         @Override
trySplit()1660         public Spliterator.OfLong trySplit() {
1661             HoldingLongConsumer holder = new HoldingLongConsumer();
1662             long s = est;
1663             if (s > 1 && tryAdvance(holder)) {
1664                 int n = batch + BATCH_UNIT;
1665                 if (n > s)
1666                     n = (int) s;
1667                 if (n > MAX_BATCH)
1668                     n = MAX_BATCH;
1669                 long[] a = new long[n];
1670                 int j = 0;
1671                 do { a[j] = holder.value; } while (++j < n && tryAdvance(holder));
1672                 batch = j;
1673                 if (est != Long.MAX_VALUE) {
1674                     est -= j;
1675                     return new LongArraySpliterator(a, 0, j, characteristics);
1676                 }
1677                 return new LongArraySpliterator(a, 0, j, characteristics, Long.MAX_VALUE / 2);
1678             }
1679             return null;
1680         }
1681 
1682         /**
1683          * {@inheritDoc}
1684          *
1685          * @implSpec
1686          * This implementation returns the estimated size as reported when
1687          * created and, if the estimate size is known, decreases in size when
1688          * split.
1689          */
1690         @Override
estimateSize()1691         public long estimateSize() {
1692             return est;
1693         }
1694 
1695         /**
1696          * {@inheritDoc}
1697          *
1698          * @implSpec
1699          * This implementation returns the characteristics as reported when
1700          * created.
1701          */
1702         @Override
characteristics()1703         public int characteristics() {
1704             return characteristics;
1705         }
1706     }
1707 
1708     /**
1709      * An abstract {@code Spliterator.OfDouble} that implements
1710      * {@code trySplit} to permit limited parallelism.
1711      *
1712      * <p>To implement a spliterator an extending class need only
1713      * implement {@link #tryAdvance(java.util.function.DoubleConsumer)
1714      * tryAdvance}.  The extending class should override
1715      * {@link #forEachRemaining(java.util.function.DoubleConsumer) forEachRemaining}
1716      * if it can provide a more performant implementation.
1717      *
1718      * @apiNote
1719      * This class is a useful aid for creating a spliterator when it is not
1720      * possible or difficult to efficiently partition elements in a manner
1721      * allowing balanced parallel computation.
1722      *
1723      * <p>An alternative to using this class, that also permits limited
1724      * parallelism, is to create a spliterator from an iterator
1725      * (see {@link #spliterator(java.util.PrimitiveIterator.OfDouble, long, int)}.
1726      * Depending on the circumstances using an iterator may be easier or more
1727      * convenient than extending this class. For example, if there is already an
1728      * iterator available to use then there is no need to extend this class.
1729      *
1730      * @see #spliterator(java.util.PrimitiveIterator.OfDouble, long, int)
1731      * @since 1.8
1732      */
1733     public abstract static class AbstractDoubleSpliterator implements Spliterator.OfDouble {
1734         static final int MAX_BATCH = AbstractSpliterator.MAX_BATCH;
1735         static final int BATCH_UNIT = AbstractSpliterator.BATCH_UNIT;
1736         private final int characteristics;
1737         private long est;             // size estimate
1738         private int batch;            // batch size for splits
1739 
1740         /**
1741          * Creates a spliterator reporting the given estimated size and
1742          * characteristics.
1743          *
1744          * @param est the estimated size of this spliterator if known, otherwise
1745          *        {@code Long.MAX_VALUE}.
1746          * @param additionalCharacteristics properties of this spliterator's
1747          *        source or elements.  If {@code SIZED} is reported then this
1748          *        spliterator will additionally report {@code SUBSIZED}.
1749          */
AbstractDoubleSpliterator(long est, int additionalCharacteristics)1750         protected AbstractDoubleSpliterator(long est, int additionalCharacteristics) {
1751             this.est = est;
1752             this.characteristics = ((additionalCharacteristics & Spliterator.SIZED) != 0)
1753                                    ? additionalCharacteristics | Spliterator.SUBSIZED
1754                                    : additionalCharacteristics;
1755         }
1756 
1757         static final class HoldingDoubleConsumer implements DoubleConsumer {
1758             double value;
1759 
1760             @Override
accept(double value)1761             public void accept(double value) {
1762                 this.value = value;
1763             }
1764         }
1765 
1766         /**
1767          * {@inheritDoc}
1768          *
1769          * This implementation permits limited parallelism.
1770          */
1771         @Override
trySplit()1772         public Spliterator.OfDouble trySplit() {
1773             HoldingDoubleConsumer holder = new HoldingDoubleConsumer();
1774             long s = est;
1775             if (s > 1 && tryAdvance(holder)) {
1776                 int n = batch + BATCH_UNIT;
1777                 if (n > s)
1778                     n = (int) s;
1779                 if (n > MAX_BATCH)
1780                     n = MAX_BATCH;
1781                 double[] a = new double[n];
1782                 int j = 0;
1783                 do { a[j] = holder.value; } while (++j < n && tryAdvance(holder));
1784                 batch = j;
1785                 if (est != Long.MAX_VALUE) {
1786                     est -= j;
1787                     return new DoubleArraySpliterator(a, 0, j, characteristics);
1788                 }
1789                 return new DoubleArraySpliterator(a, 0, j, characteristics, Long.MAX_VALUE / 2);
1790             }
1791             return null;
1792         }
1793 
1794         /**
1795          * {@inheritDoc}
1796          *
1797          * @implSpec
1798          * This implementation returns the estimated size as reported when
1799          * created and, if the estimate size is known, decreases in size when
1800          * split.
1801          */
1802         @Override
estimateSize()1803         public long estimateSize() {
1804             return est;
1805         }
1806 
1807         /**
1808          * {@inheritDoc}
1809          *
1810          * @implSpec
1811          * This implementation returns the characteristics as reported when
1812          * created.
1813          */
1814         @Override
characteristics()1815         public int characteristics() {
1816             return characteristics;
1817         }
1818     }
1819 
1820     // Iterator-based Spliterators
1821 
1822     /**
1823      * A Spliterator using a given Iterator for element
1824      * operations. The spliterator implements {@code trySplit} to
1825      * permit limited parallelism.
1826      */
1827     static class IteratorSpliterator<T> implements Spliterator<T> {
1828         static final int BATCH_UNIT = 1 << 10;  // batch array size increment
1829         static final int MAX_BATCH = 1 << 25;  // max batch array size;
1830         private final Collection<? extends T> collection; // null OK
1831         private Iterator<? extends T> it;
1832         private final int characteristics;
1833         private long est;             // size estimate
1834         private int batch;            // batch size for splits
1835 
1836         /**
1837          * Creates a spliterator using the given
1838          * collection's {@link java.util.Collection#iterator() iterator} for traversal,
1839          * and reporting its {@link java.util.Collection#size() size} as its initial
1840          * size.
1841          *
1842          * @param collection the collection
1843          * @param characteristics properties of this spliterator's
1844          *        source or elements.
1845          */
IteratorSpliterator(Collection<? extends T> collection, int characteristics)1846         public IteratorSpliterator(Collection<? extends T> collection, int characteristics) {
1847             this.collection = collection;
1848             this.it = null;
1849             this.characteristics = (characteristics & Spliterator.CONCURRENT) == 0
1850                                    ? characteristics | Spliterator.SIZED | Spliterator.SUBSIZED
1851                                    : characteristics;
1852         }
1853 
1854         /**
1855          * Creates a spliterator using the given iterator
1856          * for traversal, and reporting the given initial size
1857          * and characteristics.
1858          *
1859          * @param iterator the iterator for the source
1860          * @param size the number of elements in the source
1861          * @param characteristics properties of this spliterator's
1862          * source or elements.
1863          */
IteratorSpliterator(Iterator<? extends T> iterator, long size, int characteristics)1864         public IteratorSpliterator(Iterator<? extends T> iterator, long size, int characteristics) {
1865             this.collection = null;
1866             this.it = iterator;
1867             this.est = size;
1868             this.characteristics = (characteristics & Spliterator.CONCURRENT) == 0
1869                                    ? characteristics | Spliterator.SIZED | Spliterator.SUBSIZED
1870                                    : characteristics;
1871         }
1872 
1873         /**
1874          * Creates a spliterator using the given iterator
1875          * for traversal, and reporting the given initial size
1876          * and characteristics.
1877          *
1878          * @param iterator the iterator for the source
1879          * @param characteristics properties of this spliterator's
1880          * source or elements.
1881          */
IteratorSpliterator(Iterator<? extends T> iterator, int characteristics)1882         public IteratorSpliterator(Iterator<? extends T> iterator, int characteristics) {
1883             this.collection = null;
1884             this.it = iterator;
1885             this.est = Long.MAX_VALUE;
1886             this.characteristics = characteristics & ~(Spliterator.SIZED | Spliterator.SUBSIZED);
1887         }
1888 
1889         @Override
trySplit()1890         public Spliterator<T> trySplit() {
1891             /*
1892              * Split into arrays of arithmetically increasing batch
1893              * sizes.  This will only improve parallel performance if
1894              * per-element Consumer actions are more costly than
1895              * transferring them into an array.  The use of an
1896              * arithmetic progression in split sizes provides overhead
1897              * vs parallelism bounds that do not particularly favor or
1898              * penalize cases of lightweight vs heavyweight element
1899              * operations, across combinations of #elements vs #cores,
1900              * whether or not either are known.  We generate
1901              * O(sqrt(#elements)) splits, allowing O(sqrt(#cores))
1902              * potential speedup.
1903              */
1904             Iterator<? extends T> i;
1905             long s;
1906             if ((i = it) == null) {
1907                 i = it = collection.iterator();
1908                 s = est = (long) collection.size();
1909             }
1910             else
1911                 s = est;
1912             if (s > 1 && i.hasNext()) {
1913                 int n = batch + BATCH_UNIT;
1914                 if (n > s)
1915                     n = (int) s;
1916                 if (n > MAX_BATCH)
1917                     n = MAX_BATCH;
1918                 Object[] a = new Object[n];
1919                 int j = 0;
1920                 do { a[j] = i.next(); } while (++j < n && i.hasNext());
1921                 batch = j;
1922                 if (est != Long.MAX_VALUE) {
1923                     est -= j;
1924                     return new ArraySpliterator<>(a, 0, j, characteristics);
1925                 }
1926                 return new ArraySpliterator<>(a, 0, j, characteristics, Long.MAX_VALUE / 2);
1927             }
1928             return null;
1929         }
1930 
1931         @Override
forEachRemaining(Consumer<? super T> action)1932         public void forEachRemaining(Consumer<? super T> action) {
1933             if (action == null) throw new NullPointerException();
1934             Iterator<? extends T> i;
1935             if ((i = it) == null) {
1936                 i = it = collection.iterator();
1937                 est = (long)collection.size();
1938             }
1939             i.forEachRemaining(action);
1940         }
1941 
1942         @Override
tryAdvance(Consumer<? super T> action)1943         public boolean tryAdvance(Consumer<? super T> action) {
1944             if (action == null) throw new NullPointerException();
1945             if (it == null) {
1946                 it = collection.iterator();
1947                 est = (long) collection.size();
1948             }
1949             if (it.hasNext()) {
1950                 action.accept(it.next());
1951                 return true;
1952             }
1953             return false;
1954         }
1955 
1956         @Override
estimateSize()1957         public long estimateSize() {
1958             if (it == null) {
1959                 it = collection.iterator();
1960                 return est = (long)collection.size();
1961             }
1962             return est;
1963         }
1964 
1965         @Override
characteristics()1966         public int characteristics() { return characteristics; }
1967 
1968         @Override
getComparator()1969         public Comparator<? super T> getComparator() {
1970             if (hasCharacteristics(Spliterator.SORTED))
1971                 return null;
1972             throw new IllegalStateException();
1973         }
1974     }
1975 
1976     /**
1977      * A Spliterator.OfInt using a given IntStream.IntIterator for element
1978      * operations. The spliterator implements {@code trySplit} to
1979      * permit limited parallelism.
1980      */
1981     static final class IntIteratorSpliterator implements Spliterator.OfInt {
1982         static final int BATCH_UNIT = IteratorSpliterator.BATCH_UNIT;
1983         static final int MAX_BATCH = IteratorSpliterator.MAX_BATCH;
1984         private final PrimitiveIterator.OfInt 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          */
IntIteratorSpliterator(PrimitiveIterator.OfInt iterator, long size, int characteristics)1999         public IntIteratorSpliterator(PrimitiveIterator.OfInt 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          */
IntIteratorSpliterator(PrimitiveIterator.OfInt iterator, int characteristics)2016         public IntIteratorSpliterator(PrimitiveIterator.OfInt 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 OfInt trySplit() {
2024             PrimitiveIterator.OfInt 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                 int[] a = new int[n];
2033                 int j = 0;
2034                 do { a[j] = i.nextInt(); } while (++j < n && i.hasNext());
2035                 batch = j;
2036                 if (est != Long.MAX_VALUE) {
2037                     est -= j;
2038                     return new IntArraySpliterator(a, 0, j, characteristics);
2039                 }
2040                 return new IntArraySpliterator(a, 0, j, characteristics, Long.MAX_VALUE / 2);
2041             }
2042             return null;
2043         }
2044 
2045         @Override
forEachRemaining(IntConsumer action)2046         public void forEachRemaining(IntConsumer action) {
2047             if (action == null) throw new NullPointerException();
2048             it.forEachRemaining(action);
2049         }
2050 
2051         @Override
tryAdvance(IntConsumer action)2052         public boolean tryAdvance(IntConsumer action) {
2053             if (action == null) throw new NullPointerException();
2054             if (it.hasNext()) {
2055                 action.accept(it.nextInt());
2056                 return true;
2057             }
2058             return false;
2059         }
2060 
2061         @Override
estimateSize()2062         public long estimateSize() {
2063             return est;
2064         }
2065 
2066         @Override
characteristics()2067         public int characteristics() { return characteristics; }
2068 
2069         @Override
getComparator()2070         public Comparator<? super Integer> getComparator() {
2071             if (hasCharacteristics(Spliterator.SORTED))
2072                 return null;
2073             throw new IllegalStateException();
2074         }
2075     }
2076 
2077     static final class LongIteratorSpliterator implements Spliterator.OfLong {
2078         static final int BATCH_UNIT = IteratorSpliterator.BATCH_UNIT;
2079         static final int MAX_BATCH = IteratorSpliterator.MAX_BATCH;
2080         private final PrimitiveIterator.OfLong it;
2081         private final int characteristics;
2082         private long est;             // size estimate
2083         private int batch;            // batch size for splits
2084 
2085         /**
2086          * Creates a spliterator using the given iterator
2087          * for traversal, and reporting the given initial size
2088          * and characteristics.
2089          *
2090          * @param iterator the iterator for the source
2091          * @param size the number of elements in the source
2092          * @param characteristics properties of this spliterator's
2093          * source or elements.
2094          */
LongIteratorSpliterator(PrimitiveIterator.OfLong iterator, long size, int characteristics)2095         public LongIteratorSpliterator(PrimitiveIterator.OfLong iterator, long size, int characteristics) {
2096             this.it = iterator;
2097             this.est = size;
2098             this.characteristics = (characteristics & Spliterator.CONCURRENT) == 0
2099                                    ? characteristics | Spliterator.SIZED | Spliterator.SUBSIZED
2100                                    : characteristics;
2101         }
2102 
2103         /**
2104          * Creates a spliterator using the given iterator for a
2105          * source of unknown size, reporting the given
2106          * characteristics.
2107          *
2108          * @param iterator the iterator for the source
2109          * @param characteristics properties of this spliterator's
2110          * source or elements.
2111          */
LongIteratorSpliterator(PrimitiveIterator.OfLong iterator, int characteristics)2112         public LongIteratorSpliterator(PrimitiveIterator.OfLong iterator, int characteristics) {
2113             this.it = iterator;
2114             this.est = Long.MAX_VALUE;
2115             this.characteristics = characteristics & ~(Spliterator.SIZED | Spliterator.SUBSIZED);
2116         }
2117 
2118         @Override
trySplit()2119         public OfLong trySplit() {
2120             PrimitiveIterator.OfLong i = it;
2121             long s = est;
2122             if (s > 1 && i.hasNext()) {
2123                 int n = batch + BATCH_UNIT;
2124                 if (n > s)
2125                     n = (int) s;
2126                 if (n > MAX_BATCH)
2127                     n = MAX_BATCH;
2128                 long[] a = new long[n];
2129                 int j = 0;
2130                 do { a[j] = i.nextLong(); } while (++j < n && i.hasNext());
2131                 batch = j;
2132                 if (est != Long.MAX_VALUE) {
2133                     est -= j;
2134                     return new LongArraySpliterator(a, 0, j, characteristics);
2135                 }
2136                 return new LongArraySpliterator(a, 0, j, characteristics, Long.MAX_VALUE / 2);
2137             }
2138             return null;
2139         }
2140 
2141         @Override
forEachRemaining(LongConsumer action)2142         public void forEachRemaining(LongConsumer action) {
2143             if (action == null) throw new NullPointerException();
2144             it.forEachRemaining(action);
2145         }
2146 
2147         @Override
tryAdvance(LongConsumer action)2148         public boolean tryAdvance(LongConsumer action) {
2149             if (action == null) throw new NullPointerException();
2150             if (it.hasNext()) {
2151                 action.accept(it.nextLong());
2152                 return true;
2153             }
2154             return false;
2155         }
2156 
2157         @Override
estimateSize()2158         public long estimateSize() {
2159             return est;
2160         }
2161 
2162         @Override
characteristics()2163         public int characteristics() { return characteristics; }
2164 
2165         @Override
getComparator()2166         public Comparator<? super Long> getComparator() {
2167             if (hasCharacteristics(Spliterator.SORTED))
2168                 return null;
2169             throw new IllegalStateException();
2170         }
2171     }
2172 
2173     static final class DoubleIteratorSpliterator implements Spliterator.OfDouble {
2174         static final int BATCH_UNIT = IteratorSpliterator.BATCH_UNIT;
2175         static final int MAX_BATCH = IteratorSpliterator.MAX_BATCH;
2176         private final PrimitiveIterator.OfDouble it;
2177         private final int characteristics;
2178         private long est;             // size estimate
2179         private int batch;            // batch size for splits
2180 
2181         /**
2182          * Creates a spliterator using the given iterator
2183          * for traversal, and reporting the given initial size
2184          * and characteristics.
2185          *
2186          * @param iterator the iterator for the source
2187          * @param size the number of elements in the source
2188          * @param characteristics properties of this spliterator's
2189          * source or elements.
2190          */
DoubleIteratorSpliterator(PrimitiveIterator.OfDouble iterator, long size, int characteristics)2191         public DoubleIteratorSpliterator(PrimitiveIterator.OfDouble iterator, long size, int characteristics) {
2192             this.it = iterator;
2193             this.est = size;
2194             this.characteristics = (characteristics & Spliterator.CONCURRENT) == 0
2195                                    ? characteristics | Spliterator.SIZED | Spliterator.SUBSIZED
2196                                    : characteristics;
2197         }
2198 
2199         /**
2200          * Creates a spliterator using the given iterator for a
2201          * source of unknown size, reporting the given
2202          * characteristics.
2203          *
2204          * @param iterator the iterator for the source
2205          * @param characteristics properties of this spliterator's
2206          * source or elements.
2207          */
DoubleIteratorSpliterator(PrimitiveIterator.OfDouble iterator, int characteristics)2208         public DoubleIteratorSpliterator(PrimitiveIterator.OfDouble iterator, int characteristics) {
2209             this.it = iterator;
2210             this.est = Long.MAX_VALUE;
2211             this.characteristics = characteristics & ~(Spliterator.SIZED | Spliterator.SUBSIZED);
2212         }
2213 
2214         @Override
trySplit()2215         public OfDouble trySplit() {
2216             PrimitiveIterator.OfDouble i = it;
2217             long s = est;
2218             if (s > 1 && i.hasNext()) {
2219                 int n = batch + BATCH_UNIT;
2220                 if (n > s)
2221                     n = (int) s;
2222                 if (n > MAX_BATCH)
2223                     n = MAX_BATCH;
2224                 double[] a = new double[n];
2225                 int j = 0;
2226                 do { a[j] = i.nextDouble(); } while (++j < n && i.hasNext());
2227                 batch = j;
2228                 if (est != Long.MAX_VALUE) {
2229                     est -= j;
2230                     return new DoubleArraySpliterator(a, 0, j, characteristics);
2231                 }
2232                 return new DoubleArraySpliterator(a, 0, j, characteristics, Long.MAX_VALUE / 2);
2233             }
2234             return null;
2235         }
2236 
2237         @Override
forEachRemaining(DoubleConsumer action)2238         public void forEachRemaining(DoubleConsumer action) {
2239             if (action == null) throw new NullPointerException();
2240             it.forEachRemaining(action);
2241         }
2242 
2243         @Override
tryAdvance(DoubleConsumer action)2244         public boolean tryAdvance(DoubleConsumer action) {
2245             if (action == null) throw new NullPointerException();
2246             if (it.hasNext()) {
2247                 action.accept(it.nextDouble());
2248                 return true;
2249             }
2250             return false;
2251         }
2252 
2253         @Override
estimateSize()2254         public long estimateSize() {
2255             return est;
2256         }
2257 
2258         @Override
characteristics()2259         public int characteristics() { return characteristics; }
2260 
2261         @Override
getComparator()2262         public Comparator<? super Double> getComparator() {
2263             if (hasCharacteristics(Spliterator.SORTED))
2264                 return null;
2265             throw new IllegalStateException();
2266         }
2267     }
2268 }
2269