1 /* 2 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package java.util.stream; 26 27 import java.util.Comparator; 28 import java.util.Spliterator; 29 import java.util.function.Consumer; 30 import java.util.function.DoubleConsumer; 31 import java.util.function.IntConsumer; 32 import java.util.function.LongConsumer; 33 34 /** 35 * Utility methods for operating on and creating streams. 36 * 37 * <p>Unless otherwise stated, streams are created as sequential streams. A 38 * sequential stream can be transformed into a parallel stream by calling the 39 * {@code parallel()} method on the created stream. 40 * 41 * @since 1.8 42 */ 43 final class Streams { 44 45 private Streams() { 46 throw new Error("no instances"); 47 } 48 49 /** 50 * An object instance representing no value, that cannot be an actual 51 * data element of a stream. Used when processing streams that can contain 52 * {@code null} elements to distinguish between a {@code null} value and no 53 * value. 54 */ 55 static final Object NONE = new Object(); 56 57 /** 58 * An {@code int} range spliterator. 59 */ 60 static final class RangeIntSpliterator implements Spliterator.OfInt { 61 // Can never be greater that upTo, this avoids overflow if upper bound 62 // is Integer.MAX_VALUE 63 // All elements are traversed if from == upTo & last == 0 64 private int from; 65 private final int upTo; 66 // 1 if the range is closed and the last element has not been traversed 67 // Otherwise, 0 if the range is open, or is a closed range and all 68 // elements have been traversed 69 private int last; 70 71 RangeIntSpliterator(int from, int upTo, boolean closed) { 72 this(from, upTo, closed ? 1 : 0); 73 } 74 75 private RangeIntSpliterator(int from, int upTo, int last) { 76 this.from = from; 77 this.upTo = upTo; 78 this.last = last; 79 } 80 81 @Override 82 public boolean tryAdvance(IntConsumer consumer) { 83 final int i = from; 84 if (i < upTo) { 85 from++; 86 consumer.accept(i); 87 return true; 88 } 89 else if (last > 0) { 90 last = 0; 91 consumer.accept(i); 92 return true; 93 } 94 return false; 95 } 96 97 @Override 98 public void forEachRemaining(IntConsumer consumer) { 99 int i = from; 100 final int hUpTo = upTo; 101 int hLast = last; 102 from = upTo; 103 last = 0; 104 while (i < hUpTo) { 105 consumer.accept(i++); 106 } 107 if (hLast > 0) { 108 // Last element of closed range 109 consumer.accept(i); 110 } 111 } 112 113 @Override 114 public long estimateSize() { 115 // Ensure ranges of size > Integer.MAX_VALUE report the correct size 116 return ((long) upTo) - from + last; 117 } 118 119 @Override 120 public int characteristics() { 121 return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED | 122 Spliterator.IMMUTABLE | Spliterator.NONNULL | 123 Spliterator.DISTINCT | Spliterator.SORTED; 124 } 125 126 @Override 127 public Comparator<? super Integer> getComparator() { 128 return null; 129 } 130 131 @Override 132 public Spliterator.OfInt trySplit() { 133 long size = estimateSize(); 134 return size <= 1 135 ? null 136 // Left split always has a half-open range 137 : new RangeIntSpliterator(from, from = from + splitPoint(size), 0); 138 } 139 140 /** 141 * The spliterator size below which the spliterator will be split 142 * at the mid-point to produce balanced splits. Above this size the 143 * spliterator will be split at a ratio of 144 * 1:(RIGHT_BALANCED_SPLIT_RATIO - 1) 145 * to produce right-balanced splits. 146 * 147 * <p>Such splitting ensures that for very large ranges that the left 148 * side of the range will more likely be processed at a lower-depth 149 * than a balanced tree at the expense of a higher-depth for the right 150 * side of the range. 151 * 152 * <p>This is optimized for cases such as IntStream.ints() that is 153 * implemented as range of 0 to Integer.MAX_VALUE but is likely to be 154 * augmented with a limit operation that limits the number of elements 155 * to a count lower than this threshold. 156 */ 157 private static final int BALANCED_SPLIT_THRESHOLD = 1 << 24; 158 159 /** 160 * The split ratio of the left and right split when the spliterator 161 * size is above BALANCED_SPLIT_THRESHOLD. 162 */ 163 private static final int RIGHT_BALANCED_SPLIT_RATIO = 1 << 3; 164 165 private int splitPoint(long size) { 166 int d = (size < BALANCED_SPLIT_THRESHOLD) ? 2 : RIGHT_BALANCED_SPLIT_RATIO; 167 // 2 <= size <= 2^32 168 return (int) (size / d); 169 } 170 } 171 172 /** 173 * A {@code long} range spliterator. 174 * 175 * This implementation cannot be used for ranges whose size is greater 176 * than Long.MAX_VALUE 177 */ 178 static final class RangeLongSpliterator implements Spliterator.OfLong { 179 // Can never be greater that upTo, this avoids overflow if upper bound 180 // is Long.MAX_VALUE 181 // All elements are traversed if from == upTo & last == 0 182 private long from; 183 private final long upTo; 184 // 1 if the range is closed and the last element has not been traversed 185 // Otherwise, 0 if the range is open, or is a closed range and all 186 // elements have been traversed 187 private int last; 188 189 RangeLongSpliterator(long from, long upTo, boolean closed) { 190 this(from, upTo, closed ? 1 : 0); 191 } 192 193 private RangeLongSpliterator(long from, long upTo, int last) { 194 assert upTo - from + last > 0; 195 this.from = from; 196 this.upTo = upTo; 197 this.last = last; 198 } 199 200 @Override 201 public boolean tryAdvance(LongConsumer consumer) { 202 final long i = from; 203 if (i < upTo) { 204 from++; 205 consumer.accept(i); 206 return true; 207 } 208 else if (last > 0) { 209 last = 0; 210 consumer.accept(i); 211 return true; 212 } 213 return false; 214 } 215 216 @Override 217 public void forEachRemaining(LongConsumer consumer) { 218 long i = from; 219 final long hUpTo = upTo; 220 int hLast = last; 221 from = upTo; 222 last = 0; 223 while (i < hUpTo) { 224 consumer.accept(i++); 225 } 226 if (hLast > 0) { 227 // Last element of closed range 228 consumer.accept(i); 229 } 230 } 231 232 @Override 233 public long estimateSize() { 234 return upTo - from + last; 235 } 236 237 @Override 238 public int characteristics() { 239 return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED | 240 Spliterator.IMMUTABLE | Spliterator.NONNULL | 241 Spliterator.DISTINCT | Spliterator.SORTED; 242 } 243 244 @Override 245 public Comparator<? super Long> getComparator() { 246 return null; 247 } 248 249 @Override 250 public Spliterator.OfLong trySplit() { 251 long size = estimateSize(); 252 return size <= 1 253 ? null 254 // Left split always has a half-open range 255 : new RangeLongSpliterator(from, from = from + splitPoint(size), 0); 256 } 257 258 /** 259 * The spliterator size below which the spliterator will be split 260 * at the mid-point to produce balanced splits. Above this size the 261 * spliterator will be split at a ratio of 262 * 1:(RIGHT_BALANCED_SPLIT_RATIO - 1) 263 * to produce right-balanced splits. 264 * 265 * <p>Such splitting ensures that for very large ranges that the left 266 * side of the range will more likely be processed at a lower-depth 267 * than a balanced tree at the expense of a higher-depth for the right 268 * side of the range. 269 * 270 * <p>This is optimized for cases such as LongStream.longs() that is 271 * implemented as range of 0 to Long.MAX_VALUE but is likely to be 272 * augmented with a limit operation that limits the number of elements 273 * to a count lower than this threshold. 274 */ 275 private static final long BALANCED_SPLIT_THRESHOLD = 1 << 24; 276 277 /** 278 * The split ratio of the left and right split when the spliterator 279 * size is above BALANCED_SPLIT_THRESHOLD. 280 */ 281 private static final long RIGHT_BALANCED_SPLIT_RATIO = 1 << 3; 282 283 private long splitPoint(long size) { 284 long d = (size < BALANCED_SPLIT_THRESHOLD) ? 2 : RIGHT_BALANCED_SPLIT_RATIO; 285 // 2 <= size <= Long.MAX_VALUE 286 return size / d; 287 } 288 } 289 290 private static abstract class AbstractStreamBuilderImpl<T, S extends Spliterator<T>> implements Spliterator<T> { 291 // >= 0 when building, < 0 when built 292 // -1 == no elements 293 // -2 == one element, held by first 294 // -3 == two or more elements, held by buffer 295 int count; 296 297 // Spliterator implementation for 0 or 1 element 298 // count == -1 for no elements 299 // count == -2 for one element held by first 300 301 @Override 302 public S trySplit() { 303 return null; 304 } 305 306 @Override 307 public long estimateSize() { 308 return -count - 1; 309 } 310 311 @Override 312 public int characteristics() { 313 return Spliterator.SIZED | Spliterator.SUBSIZED | 314 Spliterator.ORDERED | Spliterator.IMMUTABLE; 315 } 316 } 317 318 static final class StreamBuilderImpl<T> 319 extends AbstractStreamBuilderImpl<T, Spliterator<T>> 320 implements Stream.Builder<T> { 321 // The first element in the stream 322 // valid if count == 1 323 T first; 324 325 // The first and subsequent elements in the stream 326 // non-null if count == 2 327 SpinedBuffer<T> buffer; 328 329 /** 330 * Constructor for building a stream of 0 or more elements. 331 */ 332 StreamBuilderImpl() { } 333 334 /** 335 * Constructor for a singleton stream. 336 * 337 * @param t the single element 338 */ 339 StreamBuilderImpl(T t) { 340 first = t; 341 count = -2; 342 } 343 344 // StreamBuilder implementation 345 346 @Override 347 public void accept(T t) { 348 if (count == 0) { 349 first = t; 350 count++; 351 } 352 else if (count > 0) { 353 if (buffer == null) { 354 buffer = new SpinedBuffer<>(); 355 buffer.accept(first); 356 count++; 357 } 358 359 buffer.accept(t); 360 } 361 else { 362 throw new IllegalStateException(); 363 } 364 } 365 366 public Stream.Builder<T> add(T t) { 367 accept(t); 368 return this; 369 } 370 371 @Override 372 public Stream<T> build() { 373 int c = count; 374 if (c >= 0) { 375 // Switch count to negative value signalling the builder is built 376 count = -count - 1; 377 // Use this spliterator if 0 or 1 elements, otherwise use 378 // the spliterator of the spined buffer 379 return (c < 2) ? StreamSupport.stream(this, false) : StreamSupport.stream(buffer.spliterator(), false); 380 } 381 382 throw new IllegalStateException(); 383 } 384 385 // Spliterator implementation for 0 or 1 element 386 // count == -1 for no elements 387 // count == -2 for one element held by first 388 389 @Override 390 public boolean tryAdvance(Consumer<? super T> action) { 391 if (count == -2) { 392 action.accept(first); 393 count = -1; 394 return true; 395 } 396 else { 397 return false; 398 } 399 } 400 401 @Override 402 public void forEachRemaining(Consumer<? super T> action) { 403 if (count == -2) { 404 action.accept(first); 405 count = -1; 406 } 407 } 408 } 409 410 static final class IntStreamBuilderImpl 411 extends AbstractStreamBuilderImpl<Integer, Spliterator.OfInt> 412 implements IntStream.Builder, Spliterator.OfInt { 413 // The first element in the stream 414 // valid if count == 1 415 int first; 416 417 // The first and subsequent elements in the stream 418 // non-null if count == 2 419 SpinedBuffer.OfInt buffer; 420 421 /** 422 * Constructor for building a stream of 0 or more elements. 423 */ 424 IntStreamBuilderImpl() { } 425 426 /** 427 * Constructor for a singleton stream. 428 * 429 * @param t the single element 430 */ 431 IntStreamBuilderImpl(int t) { 432 first = t; 433 count = -2; 434 } 435 436 // StreamBuilder implementation 437 438 @Override 439 public void accept(int t) { 440 if (count == 0) { 441 first = t; 442 count++; 443 } 444 else if (count > 0) { 445 if (buffer == null) { 446 buffer = new SpinedBuffer.OfInt(); 447 buffer.accept(first); 448 count++; 449 } 450 451 buffer.accept(t); 452 } 453 else { 454 throw new IllegalStateException(); 455 } 456 } 457 458 @Override 459 public IntStream build() { 460 int c = count; 461 if (c >= 0) { 462 // Switch count to negative value signalling the builder is built 463 count = -count - 1; 464 // Use this spliterator if 0 or 1 elements, otherwise use 465 // the spliterator of the spined buffer 466 return (c < 2) ? StreamSupport.intStream(this, false) : StreamSupport.intStream(buffer.spliterator(), false); 467 } 468 469 throw new IllegalStateException(); 470 } 471 472 // Spliterator implementation for 0 or 1 element 473 // count == -1 for no elements 474 // count == -2 for one element held by first 475 476 @Override 477 public boolean tryAdvance(IntConsumer action) { 478 if (count == -2) { 479 action.accept(first); 480 count = -1; 481 return true; 482 } 483 else { 484 return false; 485 } 486 } 487 488 @Override 489 public void forEachRemaining(IntConsumer action) { 490 if (count == -2) { 491 action.accept(first); 492 count = -1; 493 } 494 } 495 } 496 497 static final class LongStreamBuilderImpl 498 extends AbstractStreamBuilderImpl<Long, Spliterator.OfLong> 499 implements LongStream.Builder, Spliterator.OfLong { 500 // The first element in the stream 501 // valid if count == 1 502 long first; 503 504 // The first and subsequent elements in the stream 505 // non-null if count == 2 506 SpinedBuffer.OfLong buffer; 507 508 /** 509 * Constructor for building a stream of 0 or more elements. 510 */ 511 LongStreamBuilderImpl() { } 512 513 /** 514 * Constructor for a singleton stream. 515 * 516 * @param t the single element 517 */ 518 LongStreamBuilderImpl(long t) { 519 first = t; 520 count = -2; 521 } 522 523 // StreamBuilder implementation 524 525 @Override 526 public void accept(long t) { 527 if (count == 0) { 528 first = t; 529 count++; 530 } 531 else if (count > 0) { 532 if (buffer == null) { 533 buffer = new SpinedBuffer.OfLong(); 534 buffer.accept(first); 535 count++; 536 } 537 538 buffer.accept(t); 539 } 540 else { 541 throw new IllegalStateException(); 542 } 543 } 544 545 @Override 546 public LongStream build() { 547 int c = count; 548 if (c >= 0) { 549 // Switch count to negative value signalling the builder is built 550 count = -count - 1; 551 // Use this spliterator if 0 or 1 elements, otherwise use 552 // the spliterator of the spined buffer 553 return (c < 2) ? StreamSupport.longStream(this, false) : StreamSupport.longStream(buffer.spliterator(), false); 554 } 555 556 throw new IllegalStateException(); 557 } 558 559 // Spliterator implementation for 0 or 1 element 560 // count == -1 for no elements 561 // count == -2 for one element held by first 562 563 @Override 564 public boolean tryAdvance(LongConsumer action) { 565 if (count == -2) { 566 action.accept(first); 567 count = -1; 568 return true; 569 } 570 else { 571 return false; 572 } 573 } 574 575 @Override 576 public void forEachRemaining(LongConsumer action) { 577 if (count == -2) { 578 action.accept(first); 579 count = -1; 580 } 581 } 582 } 583 584 static final class DoubleStreamBuilderImpl 585 extends AbstractStreamBuilderImpl<Double, Spliterator.OfDouble> 586 implements DoubleStream.Builder, Spliterator.OfDouble { 587 // The first element in the stream 588 // valid if count == 1 589 double first; 590 591 // The first and subsequent elements in the stream 592 // non-null if count == 2 593 SpinedBuffer.OfDouble buffer; 594 595 /** 596 * Constructor for building a stream of 0 or more elements. 597 */ 598 DoubleStreamBuilderImpl() { } 599 600 /** 601 * Constructor for a singleton stream. 602 * 603 * @param t the single element 604 */ 605 DoubleStreamBuilderImpl(double t) { 606 first = t; 607 count = -2; 608 } 609 610 // StreamBuilder implementation 611 612 @Override 613 public void accept(double t) { 614 if (count == 0) { 615 first = t; 616 count++; 617 } 618 else if (count > 0) { 619 if (buffer == null) { 620 buffer = new SpinedBuffer.OfDouble(); 621 buffer.accept(first); 622 count++; 623 } 624 625 buffer.accept(t); 626 } 627 else { 628 throw new IllegalStateException(); 629 } 630 } 631 632 @Override 633 public DoubleStream build() { 634 int c = count; 635 if (c >= 0) { 636 // Switch count to negative value signalling the builder is built 637 count = -count - 1; 638 // Use this spliterator if 0 or 1 elements, otherwise use 639 // the spliterator of the spined buffer 640 return (c < 2) ? StreamSupport.doubleStream(this, false) : StreamSupport.doubleStream(buffer.spliterator(), false); 641 } 642 643 throw new IllegalStateException(); 644 } 645 646 // Spliterator implementation for 0 or 1 element 647 // count == -1 for no elements 648 // count == -2 for one element held by first 649 650 @Override 651 public boolean tryAdvance(DoubleConsumer action) { 652 if (count == -2) { 653 action.accept(first); 654 count = -1; 655 return true; 656 } 657 else { 658 return false; 659 } 660 } 661 662 @Override 663 public void forEachRemaining(DoubleConsumer action) { 664 if (count == -2) { 665 action.accept(first); 666 count = -1; 667 } 668 } 669 } 670 671 abstract static class ConcatSpliterator<T, T_SPLITR extends Spliterator<T>> 672 implements Spliterator<T> { 673 protected final T_SPLITR aSpliterator; 674 protected final T_SPLITR bSpliterator; 675 // True when no split has occurred, otherwise false 676 boolean beforeSplit; 677 // Never read after splitting 678 final boolean unsized; 679 680 public ConcatSpliterator(T_SPLITR aSpliterator, T_SPLITR bSpliterator) { 681 this.aSpliterator = aSpliterator; 682 this.bSpliterator = bSpliterator; 683 beforeSplit = true; 684 // The spliterator is unsized before splitting if a and b are 685 // sized and the sum of the estimates overflows 686 unsized = aSpliterator.hasCharacteristics(SIZED) 687 && aSpliterator.hasCharacteristics(SIZED) 688 && aSpliterator.estimateSize() + bSpliterator.estimateSize() < 0; 689 } 690 691 @Override 692 public T_SPLITR trySplit() { 693 T_SPLITR ret = beforeSplit ? aSpliterator : (T_SPLITR) bSpliterator.trySplit(); 694 beforeSplit = false; 695 return ret; 696 } 697 698 @Override 699 public boolean tryAdvance(Consumer<? super T> consumer) { 700 boolean hasNext; 701 if (beforeSplit) { 702 hasNext = aSpliterator.tryAdvance(consumer); 703 if (!hasNext) { 704 beforeSplit = false; 705 hasNext = bSpliterator.tryAdvance(consumer); 706 } 707 } 708 else 709 hasNext = bSpliterator.tryAdvance(consumer); 710 return hasNext; 711 } 712 713 @Override 714 public void forEachRemaining(Consumer<? super T> consumer) { 715 if (beforeSplit) 716 aSpliterator.forEachRemaining(consumer); 717 bSpliterator.forEachRemaining(consumer); 718 } 719 720 @Override 721 public long estimateSize() { 722 if (beforeSplit) { 723 // If one or both estimates are Long.MAX_VALUE then the sum 724 // will either be Long.MAX_VALUE or overflow to a negative value 725 long size = aSpliterator.estimateSize() + bSpliterator.estimateSize(); 726 return (size >= 0) ? size : Long.MAX_VALUE; 727 } 728 else { 729 return bSpliterator.estimateSize(); 730 } 731 } 732 733 @Override 734 public int characteristics() { 735 if (beforeSplit) { 736 // Concatenation loses DISTINCT and SORTED characteristics 737 return aSpliterator.characteristics() & bSpliterator.characteristics() 738 & ~(Spliterator.DISTINCT | Spliterator.SORTED 739 | (unsized ? Spliterator.SIZED | Spliterator.SUBSIZED : 0)); 740 } 741 else { 742 return bSpliterator.characteristics(); 743 } 744 } 745 746 @Override 747 public Comparator<? super T> getComparator() { 748 if (beforeSplit) 749 throw new IllegalStateException(); 750 return bSpliterator.getComparator(); 751 } 752 753 static class OfRef<T> extends ConcatSpliterator<T, Spliterator<T>> { 754 OfRef(Spliterator<T> aSpliterator, Spliterator<T> bSpliterator) { 755 super(aSpliterator, bSpliterator); 756 } 757 } 758 759 private static abstract class OfPrimitive<T, T_CONS, T_SPLITR extends Spliterator.OfPrimitive<T, T_CONS, T_SPLITR>> 760 extends ConcatSpliterator<T, T_SPLITR> 761 implements Spliterator.OfPrimitive<T, T_CONS, T_SPLITR> { 762 private OfPrimitive(T_SPLITR aSpliterator, T_SPLITR bSpliterator) { 763 super(aSpliterator, bSpliterator); 764 } 765 766 @Override 767 public boolean tryAdvance(T_CONS action) { 768 boolean hasNext; 769 if (beforeSplit) { 770 hasNext = aSpliterator.tryAdvance(action); 771 if (!hasNext) { 772 beforeSplit = false; 773 hasNext = bSpliterator.tryAdvance(action); 774 } 775 } 776 else 777 hasNext = bSpliterator.tryAdvance(action); 778 return hasNext; 779 } 780 781 @Override 782 public void forEachRemaining(T_CONS action) { 783 if (beforeSplit) 784 aSpliterator.forEachRemaining(action); 785 bSpliterator.forEachRemaining(action); 786 } 787 } 788 789 static class OfInt 790 extends ConcatSpliterator.OfPrimitive<Integer, IntConsumer, Spliterator.OfInt> 791 implements Spliterator.OfInt { 792 OfInt(Spliterator.OfInt aSpliterator, Spliterator.OfInt bSpliterator) { 793 super(aSpliterator, bSpliterator); 794 } 795 } 796 797 static class OfLong 798 extends ConcatSpliterator.OfPrimitive<Long, LongConsumer, Spliterator.OfLong> 799 implements Spliterator.OfLong { 800 OfLong(Spliterator.OfLong aSpliterator, Spliterator.OfLong bSpliterator) { 801 super(aSpliterator, bSpliterator); 802 } 803 } 804 805 static class OfDouble 806 extends ConcatSpliterator.OfPrimitive<Double, DoubleConsumer, Spliterator.OfDouble> 807 implements Spliterator.OfDouble { 808 OfDouble(Spliterator.OfDouble aSpliterator, Spliterator.OfDouble bSpliterator) { 809 super(aSpliterator, bSpliterator); 810 } 811 } 812 } 813 }