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