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