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. 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 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 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 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 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 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 an encounter order, specify 286 * {@code ORDERED}). The method {@link Arrays#spliterator(long[], int, int)} can 287 * often be used instead, which returns a spliterator that reports 288 * {@code SIZED}, {@code SUBSIZED}, {@code IMMUTABLE}, and {@code ORDERED}. 289 * 290 * @param array The array, assumed to be unmodified during use 291 * @param fromIndex The least index (inclusive) to cover 292 * @param toIndex One past the greatest index to cover 293 * @param additionalCharacteristics Additional spliterator characteristics 294 * of this spliterator's source or elements beyond {@code SIZED} and 295 * {@code SUBSIZED} which are are always reported 296 * @return A spliterator for an array 297 * @throws NullPointerException if the given array is {@code null} 298 * @throws ArrayIndexOutOfBoundsException if {@code fromIndex} is negative, 299 * {@code toIndex} is less than {@code fromIndex}, or 300 * {@code toIndex} is greater than the array size 301 * @see Arrays#spliterator(long[], int, int) 302 */ 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 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 an encounter order, specify 352 * {@code ORDERED}). The method {@link Arrays#spliterator(long[], int, int)} can 353 * often be used instead, which returns a spliterator that reports 354 * {@code SIZED}, {@code SUBSIZED}, {@code IMMUTABLE}, and {@code ORDERED}. 355 * 356 * @param array The array, assumed to be unmodified during use 357 * @param fromIndex The least index (inclusive) to cover 358 * @param toIndex One past the greatest index to cover 359 * @param additionalCharacteristics Additional spliterator characteristics 360 * of this spliterator's source or elements beyond {@code SIZED} and 361 * {@code SUBSIZED} which are are always reported 362 * @return A spliterator for an array 363 * @throws NullPointerException if the given array is {@code null} 364 * @throws ArrayIndexOutOfBoundsException if {@code fromIndex} is negative, 365 * {@code toIndex} is less than {@code fromIndex}, or 366 * {@code toIndex} is greater than the array size 367 * @see Arrays#spliterator(double[], int, int) 368 */ spliterator(double[] array, int fromIndex, int toIndex, int additionalCharacteristics)369 public static Spliterator.OfDouble spliterator(double[] array, int fromIndex, int toIndex, 370 int additionalCharacteristics) { 371 checkFromToBounds(Objects.requireNonNull(array).length, fromIndex, toIndex); 372 return new DoubleArraySpliterator(array, fromIndex, toIndex, additionalCharacteristics); 373 } 374 375 /** 376 * Validate inclusive start index and exclusive end index against the length 377 * of an array. 378 * @param arrayLength The length of the array 379 * @param origin The inclusive start index 380 * @param fence The exclusive end index 381 * @throws ArrayIndexOutOfBoundsException if the start index is greater than 382 * the end index, if the start index is negative, or the end index is 383 * greater than the array length 384 */ checkFromToBounds(int arrayLength, int origin, int fence)385 private static void checkFromToBounds(int arrayLength, int origin, int fence) { 386 if (origin > fence) { 387 throw new ArrayIndexOutOfBoundsException( 388 "origin(" + origin + ") > fence(" + fence + ")"); 389 } 390 if (origin < 0) { 391 throw new ArrayIndexOutOfBoundsException(origin); 392 } 393 if (fence > arrayLength) { 394 throw new ArrayIndexOutOfBoundsException(fence); 395 } 396 } 397 398 // Iterator-based spliterators 399 400 /** 401 * Creates a {@code Spliterator} using the given collection's 402 * {@link java.util.Collection#iterator()} as the source of elements, and 403 * reporting its {@link java.util.Collection#size()} as its initial size. 404 * 405 * <p>The spliterator is 406 * <em><a href="Spliterator.html#binding">late-binding</a></em>, inherits 407 * the <em>fail-fast</em> properties of the collection's iterator, and 408 * implements {@code trySplit} to permit limited parallelism. 409 * 410 * @param <T> Type of elements 411 * @param c The collection 412 * @param characteristics Characteristics of this spliterator's source or 413 * elements. The characteristics {@code SIZED} and {@code SUBSIZED} 414 * are additionally reported unless {@code CONCURRENT} is supplied. 415 * @return A spliterator from an iterator 416 * @throws NullPointerException if the given collection is {@code null} 417 */ spliterator(Collection<? extends T> c, int characteristics)418 public static <T> Spliterator<T> spliterator(Collection<? extends T> c, 419 int characteristics) { 420 return new IteratorSpliterator<>(Objects.requireNonNull(c), 421 characteristics); 422 } 423 424 /** 425 * Creates a {@code Spliterator} using a given {@code Iterator} 426 * as the source of elements, and with a given initially reported size. 427 * 428 * <p>The spliterator is not 429 * <em><a href="Spliterator.html#binding">late-binding</a></em>, inherits 430 * the <em>fail-fast</em> properties of the iterator, and implements 431 * {@code trySplit} to permit limited parallelism. 432 * 433 * <p>Traversal of elements should be accomplished through the spliterator. 434 * The behaviour of splitting and traversal is undefined if the iterator is 435 * operated on after the spliterator is returned, or the initially reported 436 * size is not equal to the actual number of elements in the source. 437 * 438 * @param <T> Type of elements 439 * @param iterator The iterator for the source 440 * @param size The number of elements in the source, to be reported as 441 * initial {@code estimateSize} 442 * @param characteristics Characteristics of this spliterator's source or 443 * elements. The characteristics {@code SIZED} and {@code SUBSIZED} 444 * are additionally reported unless {@code CONCURRENT} is supplied. 445 * @return A spliterator from an iterator 446 * @throws NullPointerException if the given iterator is {@code null} 447 */ spliterator(Iterator<? extends T> iterator, long size, int characteristics)448 public static <T> Spliterator<T> spliterator(Iterator<? extends T> iterator, 449 long size, 450 int characteristics) { 451 return new IteratorSpliterator<>(Objects.requireNonNull(iterator), size, 452 characteristics); 453 } 454 455 /** 456 * Creates a {@code Spliterator} using a given {@code Iterator} 457 * as the source of elements, with no initial size estimate. 458 * 459 * <p>The spliterator is not 460 * <em><a href="Spliterator.html#binding">late-binding</a></em>, inherits 461 * the <em>fail-fast</em> properties of the iterator, and implements 462 * {@code trySplit} to permit limited parallelism. 463 * 464 * <p>Traversal of elements should be accomplished through the spliterator. 465 * The behaviour of splitting and traversal is undefined if the iterator is 466 * operated on after the spliterator is returned. 467 * 468 * @param <T> Type of elements 469 * @param iterator The iterator for the source 470 * @param characteristics Characteristics of this spliterator's source 471 * or elements ({@code SIZED} and {@code SUBSIZED}, if supplied, are 472 * ignored and are not reported.) 473 * @return A spliterator from an iterator 474 * @throws NullPointerException if the given iterator is {@code null} 475 */ spliteratorUnknownSize(Iterator<? extends T> iterator, int characteristics)476 public static <T> Spliterator<T> spliteratorUnknownSize(Iterator<? extends T> iterator, 477 int characteristics) { 478 return new IteratorSpliterator<>(Objects.requireNonNull(iterator), characteristics); 479 } 480 481 /** 482 * Creates a {@code Spliterator.OfInt} using a given 483 * {@code IntStream.IntIterator} as the source of elements, and with a given 484 * initially reported size. 485 * 486 * <p>The spliterator is not 487 * <em><a href="Spliterator.html#binding">late-binding</a></em>, inherits 488 * the <em>fail-fast</em> properties of the iterator, and implements 489 * {@code trySplit} to permit limited parallelism. 490 * 491 * <p>Traversal of elements should be accomplished through the spliterator. 492 * The behaviour of splitting and traversal is undefined if the iterator is 493 * operated on after the spliterator is returned, or the initially reported 494 * size is not equal to the actual number of elements in the source. 495 * 496 * @param iterator The iterator for the source 497 * @param size The number of elements in the source, to be reported as 498 * initial {@code estimateSize}. 499 * @param characteristics Characteristics of this spliterator's source or 500 * elements. The characteristics {@code SIZED} and {@code SUBSIZED} 501 * are additionally reported unless {@code CONCURRENT} is supplied. 502 * @return A spliterator from an iterator 503 * @throws NullPointerException if the given iterator is {@code null} 504 */ spliterator(PrimitiveIterator.OfInt iterator, long size, int characteristics)505 public static Spliterator.OfInt spliterator(PrimitiveIterator.OfInt iterator, 506 long size, 507 int characteristics) { 508 return new IntIteratorSpliterator(Objects.requireNonNull(iterator), 509 size, characteristics); 510 } 511 512 /** 513 * Creates a {@code Spliterator.OfInt} using a given 514 * {@code IntStream.IntIterator} as the source of elements, with no initial 515 * size estimate. 516 * 517 * <p>The spliterator is not 518 * <em><a href="Spliterator.html#binding">late-binding</a></em>, inherits 519 * the <em>fail-fast</em> properties of the iterator, and implements 520 * {@code trySplit} to permit limited parallelism. 521 * 522 * <p>Traversal of elements should be accomplished through the spliterator. 523 * The behaviour of splitting and traversal is undefined if the iterator is 524 * operated on after the spliterator is returned. 525 * 526 * @param iterator The iterator for the source 527 * @param characteristics Characteristics of this spliterator's source 528 * or elements ({@code SIZED} and {@code SUBSIZED}, if supplied, are 529 * ignored and are not reported.) 530 * @return A spliterator from an iterator 531 * @throws NullPointerException if the given iterator is {@code null} 532 */ spliteratorUnknownSize(PrimitiveIterator.OfInt iterator, int characteristics)533 public static Spliterator.OfInt spliteratorUnknownSize(PrimitiveIterator.OfInt iterator, 534 int characteristics) { 535 return new IntIteratorSpliterator(Objects.requireNonNull(iterator), characteristics); 536 } 537 538 /** 539 * Creates a {@code Spliterator.OfLong} using a given 540 * {@code LongStream.LongIterator} as the source of elements, and with a 541 * given initially reported size. 542 * 543 * <p>The spliterator is not 544 * <em><a href="Spliterator.html#binding">late-binding</a></em>, inherits 545 * the <em>fail-fast</em> properties of the iterator, and implements 546 * {@code trySplit} to permit limited parallelism. 547 * 548 * <p>Traversal of elements should be accomplished through the spliterator. 549 * The behaviour of splitting and traversal is undefined if the iterator is 550 * operated on after the spliterator is returned, or the initially reported 551 * size is not equal to the actual number of elements in the source. 552 * 553 * @param iterator The iterator for the source 554 * @param size The number of elements in the source, to be reported as 555 * initial {@code estimateSize}. 556 * @param characteristics Characteristics of this spliterator's source or 557 * elements. The characteristics {@code SIZED} and {@code SUBSIZED} 558 * are additionally reported unless {@code CONCURRENT} is supplied. 559 * @return A spliterator from an iterator 560 * @throws NullPointerException if the given iterator is {@code null} 561 */ spliterator(PrimitiveIterator.OfLong iterator, long size, int characteristics)562 public static Spliterator.OfLong spliterator(PrimitiveIterator.OfLong iterator, 563 long size, 564 int characteristics) { 565 return new LongIteratorSpliterator(Objects.requireNonNull(iterator), 566 size, characteristics); 567 } 568 569 /** 570 * Creates a {@code Spliterator.OfLong} using a given 571 * {@code LongStream.LongIterator} as the source of elements, with no 572 * initial size estimate. 573 * 574 * <p>The spliterator is not 575 * <em><a href="Spliterator.html#binding">late-binding</a></em>, inherits 576 * the <em>fail-fast</em> properties of the iterator, and implements 577 * {@code trySplit} to permit limited parallelism. 578 * 579 * <p>Traversal of elements should be accomplished through the spliterator. 580 * The behaviour of splitting and traversal is undefined if the iterator is 581 * operated on after the spliterator is returned. 582 * 583 * @param iterator The iterator for the source 584 * @param characteristics Characteristics of this spliterator's source 585 * or elements ({@code SIZED} and {@code SUBSIZED}, if supplied, are 586 * ignored and are not reported.) 587 * @return A spliterator from an iterator 588 * @throws NullPointerException if the given iterator is {@code null} 589 */ spliteratorUnknownSize(PrimitiveIterator.OfLong iterator, int characteristics)590 public static Spliterator.OfLong spliteratorUnknownSize(PrimitiveIterator.OfLong iterator, 591 int characteristics) { 592 return new LongIteratorSpliterator(Objects.requireNonNull(iterator), characteristics); 593 } 594 595 /** 596 * Creates a {@code Spliterator.OfDouble} using a given 597 * {@code DoubleStream.DoubleIterator} as the source of elements, and with a 598 * given initially reported size. 599 * 600 * <p>The spliterator is not 601 * <em><a href="Spliterator.html#binding">late-binding</a></em>, inherits 602 * the <em>fail-fast</em> properties of the iterator, and implements 603 * {@code trySplit} to permit limited parallelism. 604 * 605 * <p>Traversal of elements should be accomplished through the spliterator. 606 * The behaviour of splitting and traversal is undefined if the iterator is 607 * operated on after the spliterator is returned, or the initially reported 608 * size is not equal to the actual number of elements in the source. 609 * 610 * @param iterator The iterator for the source 611 * @param size The number of elements in the source, to be reported as 612 * initial {@code estimateSize} 613 * @param characteristics Characteristics of this spliterator's source or 614 * elements. The characteristics {@code SIZED} and {@code SUBSIZED} 615 * are additionally reported unless {@code CONCURRENT} is supplied. 616 * @return A spliterator from an iterator 617 * @throws NullPointerException if the given iterator is {@code null} 618 */ spliterator(PrimitiveIterator.OfDouble iterator, long size, int characteristics)619 public static Spliterator.OfDouble spliterator(PrimitiveIterator.OfDouble iterator, 620 long size, 621 int characteristics) { 622 return new DoubleIteratorSpliterator(Objects.requireNonNull(iterator), 623 size, characteristics); 624 } 625 626 /** 627 * Creates a {@code Spliterator.OfDouble} using a given 628 * {@code DoubleStream.DoubleIterator} as the source of elements, with no 629 * initial size estimate. 630 * 631 * <p>The spliterator is not 632 * <em><a href="Spliterator.html#binding">late-binding</a></em>, inherits 633 * the <em>fail-fast</em> properties of the iterator, and implements 634 * {@code trySplit} to permit limited parallelism. 635 * 636 * <p>Traversal of elements should be accomplished through the spliterator. 637 * The behaviour of splitting and traversal is undefined if the iterator is 638 * operated on after the spliterator is returned. 639 * 640 * @param iterator The iterator for the source 641 * @param characteristics Characteristics of this spliterator's source 642 * or elements ({@code SIZED} and {@code SUBSIZED}, if supplied, are 643 * ignored and are not reported.) 644 * @return A spliterator from an iterator 645 * @throws NullPointerException if the given iterator is {@code null} 646 */ spliteratorUnknownSize(PrimitiveIterator.OfDouble iterator, int characteristics)647 public static Spliterator.OfDouble spliteratorUnknownSize(PrimitiveIterator.OfDouble iterator, 648 int characteristics) { 649 return new DoubleIteratorSpliterator(Objects.requireNonNull(iterator), characteristics); 650 } 651 652 // Iterators from Spliterators 653 654 /** 655 * Creates an {@code Iterator} from a {@code Spliterator}. 656 * 657 * <p>Traversal of elements should be accomplished through the iterator. 658 * The behaviour of traversal is undefined if the spliterator is operated 659 * after the iterator is returned. 660 * 661 * @param <T> Type of elements 662 * @param spliterator The spliterator 663 * @return An iterator 664 * @throws NullPointerException if the given spliterator is {@code null} 665 */ iterator(Spliterator<? extends T> spliterator)666 public static<T> Iterator<T> iterator(Spliterator<? extends T> spliterator) { 667 Objects.requireNonNull(spliterator); 668 class Adapter implements Iterator<T>, Consumer<T> { 669 boolean valueReady = false; 670 T nextElement; 671 672 @Override 673 public void accept(T t) { 674 valueReady = true; 675 nextElement = t; 676 } 677 678 @Override 679 public boolean hasNext() { 680 if (!valueReady) 681 spliterator.tryAdvance(this); 682 return valueReady; 683 } 684 685 @Override 686 public T next() { 687 if (!valueReady && !hasNext()) 688 throw new NoSuchElementException(); 689 else { 690 valueReady = false; 691 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 */ iterator(Spliterator.OfInt spliterator)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 */ iterator(Spliterator.OfLong spliterator)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 */ iterator(Spliterator.OfDouble spliterator)801 public static PrimitiveIterator.OfDouble iterator(Spliterator.OfDouble spliterator) { 802 Objects.requireNonNull(spliterator); 803 class Adapter implements PrimitiveIterator.OfDouble, DoubleConsumer { 804 boolean valueReady = false; 805 double nextElement; 806 807 @Override 808 public void accept(double t) { 809 valueReady = true; 810 nextElement = t; 811 } 812 813 @Override 814 public boolean hasNext() { 815 if (!valueReady) 816 spliterator.tryAdvance(this); 817 return valueReady; 818 } 819 820 @Override 821 public double nextDouble() { 822 if (!valueReady && !hasNext()) 823 throw new NoSuchElementException(); 824 else { 825 valueReady = false; 826 return nextElement; 827 } 828 } 829 } 830 831 return new Adapter(); 832 } 833 834 // Implementations 835 836 private static abstract class EmptySpliterator<T, S extends Spliterator<T>, C> { 837 EmptySpliterator()838 EmptySpliterator() { } 839 trySplit()840 public S trySplit() { 841 return null; 842 } 843 tryAdvance(C consumer)844 public boolean tryAdvance(C consumer) { 845 Objects.requireNonNull(consumer); 846 return false; 847 } 848 forEachRemaining(C consumer)849 public void forEachRemaining(C consumer) { 850 Objects.requireNonNull(consumer); 851 } 852 estimateSize()853 public long estimateSize() { 854 return 0; 855 } 856 characteristics()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> { OfRef()864 OfRef() { } 865 } 866 867 private static final class OfInt 868 extends EmptySpliterator<Integer, Spliterator.OfInt, IntConsumer> 869 implements Spliterator.OfInt { OfInt()870 OfInt() { } 871 } 872 873 private static final class OfLong 874 extends EmptySpliterator<Long, Spliterator.OfLong, LongConsumer> 875 implements Spliterator.OfLong { OfLong()876 OfLong() { } 877 } 878 879 private static final class OfDouble 880 extends EmptySpliterator<Double, Spliterator.OfDouble, DoubleConsumer> 881 implements Spliterator.OfDouble { OfDouble()882 OfDouble() { } 883 } 884 } 885 886 // Array-based spliterators 887 888 /** 889 * A Spliterator designed for use by sources that traverse and split 890 * elements maintained in an unmodifiable {@code Object[]} array. 891 */ 892 static final class ArraySpliterator<T> implements Spliterator<T> { 893 /** 894 * The array, explicitly typed as Object[]. Unlike in some other 895 * classes (see for example CR 6260652), we do not need to 896 * screen arguments to ensure they are exactly of type Object[] 897 * so long as no methods write into the array or serialize it, 898 * which we ensure here by defining this class as final. 899 */ 900 private final Object[] array; 901 private int index; // current index, modified on advance/split 902 private final int fence; // one past last index 903 private final int characteristics; 904 905 /** 906 * Creates a spliterator covering all of the given array. 907 * @param array the array, assumed to be unmodified during use 908 * @param additionalCharacteristics Additional spliterator characteristics 909 * of this spliterator's source or elements beyond {@code SIZED} and 910 * {@code SUBSIZED} which are are always reported 911 */ ArraySpliterator(Object[] array, int additionalCharacteristics)912 public ArraySpliterator(Object[] array, int additionalCharacteristics) { 913 this(array, 0, array.length, additionalCharacteristics); 914 } 915 916 /** 917 * Creates a spliterator covering the given array and range 918 * @param array the array, assumed to be unmodified during use 919 * @param origin the least index (inclusive) to cover 920 * @param fence one past the greatest index to cover 921 * @param additionalCharacteristics Additional spliterator characteristics 922 * of this spliterator's source or elements beyond {@code SIZED} and 923 * {@code SUBSIZED} which are are always reported 924 */ ArraySpliterator(Object[] array, int origin, int fence, int additionalCharacteristics)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 trySplit()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 forEachRemaining(Consumer<? super T> action)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 tryAdvance(Consumer<? super T> action)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 estimateSize()965 public long estimateSize() { return (long)(fence - index); } 966 967 @Override characteristics()968 public int characteristics() { 969 return characteristics; 970 } 971 972 @Override getComparator()973 public Comparator<? super T> getComparator() { 974 if (hasCharacteristics(Spliterator.SORTED)) 975 return null; 976 throw new IllegalStateException(); 977 } 978 } 979 980 /** 981 * A Spliterator.OfInt designed for use by sources that traverse and split 982 * elements maintained in an unmodifiable {@code int[]} array. 983 */ 984 static final class IntArraySpliterator implements Spliterator.OfInt { 985 private final int[] array; 986 private int index; // current index, modified on advance/split 987 private final int fence; // one past last index 988 private final int characteristics; 989 990 /** 991 * Creates a spliterator covering all of the given array. 992 * @param array the array, assumed to be unmodified during use 993 * @param additionalCharacteristics Additional spliterator characteristics 994 * of this spliterator's source or elements beyond {@code SIZED} and 995 * {@code SUBSIZED} which are are always reported 996 */ IntArraySpliterator(int[] array, int additionalCharacteristics)997 public IntArraySpliterator(int[] array, int additionalCharacteristics) { 998 this(array, 0, array.length, additionalCharacteristics); 999 } 1000 1001 /** 1002 * Creates a spliterator covering the given array and range 1003 * @param array the array, assumed to be unmodified during use 1004 * @param origin the least index (inclusive) to cover 1005 * @param fence one past the greatest index to cover 1006 * @param additionalCharacteristics Additional spliterator characteristics 1007 * of this spliterator's source or elements beyond {@code SIZED} and 1008 * {@code SUBSIZED} which are are always reported 1009 */ IntArraySpliterator(int[] array, int origin, int fence, int additionalCharacteristics)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 trySplit()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 forEachRemaining(IntConsumer action)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 tryAdvance(IntConsumer action)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 estimateSize()1048 public long estimateSize() { return (long)(fence - index); } 1049 1050 @Override characteristics()1051 public int characteristics() { 1052 return characteristics; 1053 } 1054 1055 @Override getComparator()1056 public Comparator<? super Integer> getComparator() { 1057 if (hasCharacteristics(Spliterator.SORTED)) 1058 return null; 1059 throw new IllegalStateException(); 1060 } 1061 } 1062 1063 /** 1064 * A Spliterator.OfLong designed for use by sources that traverse and split 1065 * elements maintained in an unmodifiable {@code int[]} array. 1066 */ 1067 static final class LongArraySpliterator implements Spliterator.OfLong { 1068 private final long[] array; 1069 private int index; // current index, modified on advance/split 1070 private final int fence; // one past last index 1071 private final int characteristics; 1072 1073 /** 1074 * Creates a spliterator covering all of the given array. 1075 * @param array the array, assumed to be unmodified during use 1076 * @param additionalCharacteristics Additional spliterator characteristics 1077 * of this spliterator's source or elements beyond {@code SIZED} and 1078 * {@code SUBSIZED} which are are always reported 1079 */ LongArraySpliterator(long[] array, int additionalCharacteristics)1080 public LongArraySpliterator(long[] array, int additionalCharacteristics) { 1081 this(array, 0, array.length, additionalCharacteristics); 1082 } 1083 1084 /** 1085 * Creates a spliterator covering the given array and range 1086 * @param array the array, assumed to be unmodified during use 1087 * @param origin the least index (inclusive) to cover 1088 * @param fence one past the greatest index to cover 1089 * @param additionalCharacteristics Additional spliterator characteristics 1090 * of this spliterator's source or elements beyond {@code SIZED} and 1091 * {@code SUBSIZED} which are are always reported 1092 */ LongArraySpliterator(long[] array, int origin, int fence, int additionalCharacteristics)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 trySplit()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 forEachRemaining(LongConsumer action)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 tryAdvance(LongConsumer action)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 estimateSize()1131 public long estimateSize() { return (long)(fence - index); } 1132 1133 @Override characteristics()1134 public int characteristics() { 1135 return characteristics; 1136 } 1137 1138 @Override getComparator()1139 public Comparator<? super Long> getComparator() { 1140 if (hasCharacteristics(Spliterator.SORTED)) 1141 return null; 1142 throw new IllegalStateException(); 1143 } 1144 } 1145 1146 /** 1147 * A Spliterator.OfDouble designed for use by sources that traverse and split 1148 * elements maintained in an unmodifiable {@code int[]} array. 1149 */ 1150 static final class DoubleArraySpliterator implements Spliterator.OfDouble { 1151 private final double[] array; 1152 private int index; // current index, modified on advance/split 1153 private final int fence; // one past last index 1154 private final int characteristics; 1155 1156 /** 1157 * Creates a spliterator covering all of the given array. 1158 * @param array the array, assumed to be unmodified during use 1159 * @param additionalCharacteristics Additional spliterator characteristics 1160 * of this spliterator's source or elements beyond {@code SIZED} and 1161 * {@code SUBSIZED} which are are always reported 1162 */ DoubleArraySpliterator(double[] array, int additionalCharacteristics)1163 public DoubleArraySpliterator(double[] array, int additionalCharacteristics) { 1164 this(array, 0, array.length, additionalCharacteristics); 1165 } 1166 1167 /** 1168 * Creates a spliterator covering the given array and range 1169 * @param array the array, assumed to be unmodified during use 1170 * @param origin the least index (inclusive) to cover 1171 * @param fence one past the greatest index to cover 1172 * @param additionalCharacteristics Additional spliterator characteristics 1173 * of this spliterator's source or elements beyond {@code SIZED} and 1174 * {@code SUBSIZED} which are are always reported 1175 */ DoubleArraySpliterator(double[] array, int origin, int fence, int additionalCharacteristics)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 trySplit()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 forEachRemaining(DoubleConsumer action)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 tryAdvance(DoubleConsumer action)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 estimateSize()1214 public long estimateSize() { return (long)(fence - index); } 1215 1216 @Override characteristics()1217 public int characteristics() { 1218 return characteristics; 1219 } 1220 1221 @Override getComparator()1222 public Comparator<? super Double> getComparator() { 1223 if (hasCharacteristics(Spliterator.SORTED)) 1224 return null; 1225 throw new IllegalStateException(); 1226 } 1227 } 1228 1229 // 1230 1231 /** 1232 * An abstract {@code Spliterator} that implements {@code trySplit} to 1233 * permit limited parallelism. 1234 * 1235 * <p>An extending class need only 1236 * implement {@link #tryAdvance(java.util.function.Consumer) tryAdvance}. 1237 * The extending class should override 1238 * {@link #forEachRemaining(java.util.function.Consumer) forEach} if it can 1239 * provide a more performant implementation. 1240 * 1241 * @apiNote 1242 * This class is a useful aid for creating a spliterator when it is not 1243 * possible or difficult to efficiently partition elements in a manner 1244 * allowing balanced parallel computation. 1245 * 1246 * <p>An alternative to using this class, that also permits limited 1247 * parallelism, is to create a spliterator from an iterator 1248 * (see {@link #spliterator(Iterator, long, int)}. Depending on the 1249 * circumstances using an iterator may be easier or more convenient than 1250 * extending this class, such as when there is already an iterator 1251 * available to use. 1252 * 1253 * @see #spliterator(Iterator, long, int) 1254 * @since 1.8 1255 */ 1256 public static abstract class AbstractSpliterator<T> implements Spliterator<T> { 1257 static final int BATCH_UNIT = 1 << 10; // batch array size increment 1258 static final int MAX_BATCH = 1 << 25; // max batch array size; 1259 private final int characteristics; 1260 private long est; // size estimate 1261 private int batch; // batch size for splits 1262 1263 /** 1264 * Creates a spliterator reporting the given estimated size and 1265 * additionalCharacteristics. 1266 * 1267 * @param est the estimated size of this spliterator if known, otherwise 1268 * {@code Long.MAX_VALUE}. 1269 * @param additionalCharacteristics properties of this spliterator's 1270 * source or elements. If {@code SIZED} is reported then this 1271 * spliterator will additionally report {@code SUBSIZED}. 1272 */ AbstractSpliterator(long est, int additionalCharacteristics)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 accept(T value)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 trySplit()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 estimateSize()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 characteristics()1349 public int characteristics() { 1350 return characteristics; 1351 } 1352 } 1353 1354 /** 1355 * An abstract {@code Spliterator.OfInt} that implements {@code trySplit} to 1356 * permit limited parallelism. 1357 * 1358 * <p>To implement a spliterator an extending class need only 1359 * implement {@link #tryAdvance(java.util.function.IntConsumer)} 1360 * tryAdvance}. The extending class should override 1361 * {@link #forEachRemaining(java.util.function.IntConsumer)} forEach} if it 1362 * can provide a more performant implementation. 1363 * 1364 * @apiNote 1365 * This class is a useful aid for creating a spliterator when it is not 1366 * possible or difficult to efficiently partition elements in a manner 1367 * allowing balanced parallel computation. 1368 * 1369 * <p>An alternative to using this class, that also permits limited 1370 * parallelism, is to create a spliterator from an iterator 1371 * (see {@link #spliterator(java.util.PrimitiveIterator.OfInt, long, int)}. 1372 * Depending on the circumstances using an iterator may be easier or more 1373 * convenient than extending this class. For example, if there is already an 1374 * iterator available to use then there is no need to extend this class. 1375 * 1376 * @see #spliterator(java.util.PrimitiveIterator.OfInt, long, int) 1377 * @since 1.8 1378 */ 1379 public static abstract class AbstractIntSpliterator implements Spliterator.OfInt { 1380 static final int MAX_BATCH = AbstractSpliterator.MAX_BATCH; 1381 static final int BATCH_UNIT = AbstractSpliterator.BATCH_UNIT; 1382 private final int characteristics; 1383 private long est; // size estimate 1384 private int batch; // batch size for splits 1385 1386 /** 1387 * Creates a spliterator reporting the given estimated size and 1388 * characteristics. 1389 * 1390 * @param est the estimated size of this spliterator if known, otherwise 1391 * {@code Long.MAX_VALUE}. 1392 * @param additionalCharacteristics properties of this spliterator's 1393 * source or elements. If {@code SIZED} is reported then this 1394 * spliterator will additionally report {@code SUBSIZED}. 1395 */ AbstractIntSpliterator(long est, int additionalCharacteristics)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 accept(int value)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 trySplit()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 estimateSize()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 characteristics()1459 public int characteristics() { 1460 return characteristics; 1461 } 1462 } 1463 1464 /** 1465 * An abstract {@code Spliterator.OfLong} that implements {@code trySplit} 1466 * to permit limited parallelism. 1467 * 1468 * <p>To implement a spliterator an extending class need only 1469 * implement {@link #tryAdvance(java.util.function.LongConsumer)} 1470 * tryAdvance}. The extending class should override 1471 * {@link #forEachRemaining(java.util.function.LongConsumer)} forEach} if it 1472 * can provide a more performant implementation. 1473 * 1474 * @apiNote 1475 * This class is a useful aid for creating a spliterator when it is not 1476 * possible or difficult to efficiently partition elements in a manner 1477 * allowing balanced parallel computation. 1478 * 1479 * <p>An alternative to using this class, that also permits limited 1480 * parallelism, is to create a spliterator from an iterator 1481 * (see {@link #spliterator(java.util.PrimitiveIterator.OfLong, long, int)}. 1482 * Depending on the circumstances using an iterator may be easier or more 1483 * convenient than extending this class. For example, if there is already an 1484 * iterator available to use then there is no need to extend this class. 1485 * 1486 * @see #spliterator(java.util.PrimitiveIterator.OfLong, long, int) 1487 * @since 1.8 1488 */ 1489 public static abstract class AbstractLongSpliterator implements Spliterator.OfLong { 1490 static final int MAX_BATCH = AbstractSpliterator.MAX_BATCH; 1491 static final int BATCH_UNIT = AbstractSpliterator.BATCH_UNIT; 1492 private final int characteristics; 1493 private long est; // size estimate 1494 private int batch; // batch size for splits 1495 1496 /** 1497 * Creates a spliterator reporting the given estimated size and 1498 * characteristics. 1499 * 1500 * @param est the estimated size of this spliterator if known, otherwise 1501 * {@code Long.MAX_VALUE}. 1502 * @param additionalCharacteristics properties of this spliterator's 1503 * source or elements. If {@code SIZED} is reported then this 1504 * spliterator will additionally report {@code SUBSIZED}. 1505 */ AbstractLongSpliterator(long est, int additionalCharacteristics)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 accept(long value)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 trySplit()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 estimateSize()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 characteristics()1569 public int characteristics() { 1570 return characteristics; 1571 } 1572 } 1573 1574 /** 1575 * An abstract {@code Spliterator.OfDouble} that implements 1576 * {@code trySplit} to permit limited parallelism. 1577 * 1578 * <p>To implement a spliterator an extending class need only 1579 * implement {@link #tryAdvance(java.util.function.DoubleConsumer)} 1580 * tryAdvance}. The extending class should override 1581 * {@link #forEachRemaining(java.util.function.DoubleConsumer)} forEach} if 1582 * it can provide a more performant implementation. 1583 * 1584 * @apiNote 1585 * This class is a useful aid for creating a spliterator when it is not 1586 * possible or difficult to efficiently partition elements in a manner 1587 * allowing balanced parallel computation. 1588 * 1589 * <p>An alternative to using this class, that also permits limited 1590 * parallelism, is to create a spliterator from an iterator 1591 * (see {@link #spliterator(java.util.PrimitiveIterator.OfDouble, long, int)}. 1592 * Depending on the circumstances using an iterator may be easier or more 1593 * convenient than extending this class. For example, if there is already an 1594 * iterator available to use then there is no need to extend this class. 1595 * 1596 * @see #spliterator(java.util.PrimitiveIterator.OfDouble, long, int) 1597 * @since 1.8 1598 */ 1599 public static abstract class AbstractDoubleSpliterator implements Spliterator.OfDouble { 1600 static final int MAX_BATCH = AbstractSpliterator.MAX_BATCH; 1601 static final int BATCH_UNIT = AbstractSpliterator.BATCH_UNIT; 1602 private final int characteristics; 1603 private long est; // size estimate 1604 private int batch; // batch size for splits 1605 1606 /** 1607 * Creates a spliterator reporting the given estimated size and 1608 * characteristics. 1609 * 1610 * @param est the estimated size of this spliterator if known, otherwise 1611 * {@code Long.MAX_VALUE}. 1612 * @param additionalCharacteristics properties of this spliterator's 1613 * source or elements. If {@code SIZED} is reported then this 1614 * spliterator will additionally report {@code SUBSIZED}. 1615 */ AbstractDoubleSpliterator(long est, int additionalCharacteristics)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 accept(double value)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 trySplit()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 estimateSize()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 characteristics()1679 public int characteristics() { 1680 return characteristics; 1681 } 1682 } 1683 1684 // Iterator-based Spliterators 1685 1686 /** 1687 * A Spliterator using a given Iterator for element 1688 * operations. The spliterator implements {@code trySplit} to 1689 * permit limited parallelism. 1690 */ 1691 static class IteratorSpliterator<T> implements Spliterator<T> { 1692 static final int BATCH_UNIT = 1 << 10; // batch array size increment 1693 static final int MAX_BATCH = 1 << 25; // max batch array size; 1694 private final Collection<? extends T> collection; // null OK 1695 private Iterator<? extends T> it; 1696 private final int characteristics; 1697 private long est; // size estimate 1698 private int batch; // batch size for splits 1699 1700 /** 1701 * Creates a spliterator using the given given 1702 * collection's {@link java.util.Collection#iterator()) for traversal, 1703 * and reporting its {@link java.util.Collection#size()) as its initial 1704 * size. 1705 * 1706 * @param c the collection 1707 * @param characteristics properties of this spliterator's 1708 * source or elements. 1709 */ IteratorSpliterator(Collection<? extends T> collection, int characteristics)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 */ IteratorSpliterator(Iterator<? extends T> iterator, long size, int characteristics)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 */ IteratorSpliterator(Iterator<? extends T> iterator, int characteristics)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 trySplit()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 forEachRemaining(Consumer<? super T> action)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 tryAdvance(Consumer<? super T> action)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 estimateSize()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 characteristics()1828 public int characteristics() { return characteristics; } 1829 1830 @Override getComparator()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 */ IntIteratorSpliterator(PrimitiveIterator.OfInt iterator, long size, int characteristics)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 */ IntIteratorSpliterator(PrimitiveIterator.OfInt iterator, int characteristics)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 trySplit()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 forEachRemaining(IntConsumer action)1906 public void forEachRemaining(IntConsumer action) { 1907 if (action == null) throw new NullPointerException(); 1908 it.forEachRemaining(action); 1909 } 1910 1911 @Override tryAdvance(IntConsumer action)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 estimateSize()1922 public long estimateSize() { 1923 return est; 1924 } 1925 1926 @Override characteristics()1927 public int characteristics() { return characteristics; } 1928 1929 @Override getComparator()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 */ LongIteratorSpliterator(PrimitiveIterator.OfLong iterator, long size, int characteristics)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 */ LongIteratorSpliterator(PrimitiveIterator.OfLong iterator, int characteristics)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 trySplit()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 forEachRemaining(LongConsumer action)2000 public void forEachRemaining(LongConsumer action) { 2001 if (action == null) throw new NullPointerException(); 2002 it.forEachRemaining(action); 2003 } 2004 2005 @Override tryAdvance(LongConsumer action)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 estimateSize()2016 public long estimateSize() { 2017 return est; 2018 } 2019 2020 @Override characteristics()2021 public int characteristics() { return characteristics; } 2022 2023 @Override getComparator()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 */ DoubleIteratorSpliterator(PrimitiveIterator.OfDouble iterator, long size, int characteristics)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 */ DoubleIteratorSpliterator(PrimitiveIterator.OfDouble iterator, int characteristics)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 trySplit()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 forEachRemaining(DoubleConsumer action)2094 public void forEachRemaining(DoubleConsumer action) { 2095 if (action == null) throw new NullPointerException(); 2096 it.forEachRemaining(action); 2097 } 2098 2099 @Override tryAdvance(DoubleConsumer action)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 estimateSize()2110 public long estimateSize() { 2111 return est; 2112 } 2113 2114 @Override characteristics()2115 public int characteristics() { return characteristics; } 2116 2117 @Override getComparator()2118 public Comparator<? super Double> getComparator() { 2119 if (hasCharacteristics(Spliterator.SORTED)) 2120 return null; 2121 throw new IllegalStateException(); 2122 } 2123 } 2124 } 2125