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