26
27 import java.util.Comparator;
28 import java.util.Objects;
29 import java.util.Spliterator;
30 import java.util.Spliterators;
31 import java.util.function.BiFunction;
32 import java.util.function.Consumer;
33 import java.util.function.DoubleConsumer;
34 import java.util.function.IntConsumer;
35 import java.util.function.LongConsumer;
36
37 /**
38 * Utility methods for operating on and creating streams.
39 *
40 * <p>Unless otherwise stated, streams are created as sequential streams. A
41 * sequential stream can be transformed into a parallel stream by calling the
42 * {@code parallel()} method on the created stream.
43 *
44 * @since 1.8
45 */
46 class Streams {
47
48 private Streams() {
49 throw new Error("no instances");
50 }
51
52 /**
53 * An object instance representing no value, that cannot be an actual
54 * data element of a stream. Used when processing streams that can contain
55 * {@code null} elements to distinguish between a {@code null} value and no
56 * value.
57 */
58 static final Object NONE = new Object();
59
60 /**
61 * An {@code int} range spliterator.
62 */
63 static final class RangeIntSpliterator implements Spliterator.OfInt {
64 // Can never be greater that upTo, this avoids overflow if upper bound
65 // is Integer.MAX_VALUE
66 // All elements are traversed if from == upTo & last == 0
650 // count == -1 for no elements
651 // count == -2 for one element held by first
652
653 @Override
654 public boolean tryAdvance(DoubleConsumer action) {
655 if (count == -2) {
656 action.accept(first);
657 count = -1;
658 return true;
659 }
660 else {
661 return false;
662 }
663 }
664
665 @Override
666 public void forEachRemaining(DoubleConsumer action) {
667 if (count == -2) {
668 action.accept(first);
669 count = -1;
670 }
671 }
672 }
673 }
|
26
27 import java.util.Comparator;
28 import java.util.Objects;
29 import java.util.Spliterator;
30 import java.util.Spliterators;
31 import java.util.function.BiFunction;
32 import java.util.function.Consumer;
33 import java.util.function.DoubleConsumer;
34 import java.util.function.IntConsumer;
35 import java.util.function.LongConsumer;
36
37 /**
38 * Utility methods for operating on and creating streams.
39 *
40 * <p>Unless otherwise stated, streams are created as sequential streams. A
41 * sequential stream can be transformed into a parallel stream by calling the
42 * {@code parallel()} method on the created stream.
43 *
44 * @since 1.8
45 */
46 final class Streams {
47
48 private Streams() {
49 throw new Error("no instances");
50 }
51
52 /**
53 * An object instance representing no value, that cannot be an actual
54 * data element of a stream. Used when processing streams that can contain
55 * {@code null} elements to distinguish between a {@code null} value and no
56 * value.
57 */
58 static final Object NONE = new Object();
59
60 /**
61 * An {@code int} range spliterator.
62 */
63 static final class RangeIntSpliterator implements Spliterator.OfInt {
64 // Can never be greater that upTo, this avoids overflow if upper bound
65 // is Integer.MAX_VALUE
66 // All elements are traversed if from == upTo & last == 0
650 // count == -1 for no elements
651 // count == -2 for one element held by first
652
653 @Override
654 public boolean tryAdvance(DoubleConsumer action) {
655 if (count == -2) {
656 action.accept(first);
657 count = -1;
658 return true;
659 }
660 else {
661 return false;
662 }
663 }
664
665 @Override
666 public void forEachRemaining(DoubleConsumer action) {
667 if (count == -2) {
668 action.accept(first);
669 count = -1;
670 }
671 }
672 }
673
674 abstract static class ConcatSpliterator<T, T_SPLITR extends Spliterator<T>>
675 implements Spliterator<T> {
676 protected final T_SPLITR aSpliterator;
677 protected final T_SPLITR bSpliterator;
678 // True when no split has occurred, otherwise false
679 boolean beforeSplit;
680 // Never read after splitting
681 final boolean unsized;
682
683 public ConcatSpliterator(T_SPLITR aSpliterator, T_SPLITR bSpliterator) {
684 this.aSpliterator = aSpliterator;
685 this.bSpliterator = bSpliterator;
686 beforeSplit = true;
687 // The spliterator is unsized before splitting if a and b are
688 // sized and the sum of the estimates overflows
689 unsized = aSpliterator.hasCharacteristics(SIZED)
690 && aSpliterator.hasCharacteristics(SIZED)
691 && aSpliterator.estimateSize() + bSpliterator.estimateSize() < 0;
692 }
693
694 @Override
695 public T_SPLITR trySplit() {
696 T_SPLITR ret = beforeSplit ? aSpliterator : (T_SPLITR) bSpliterator.trySplit();
697 beforeSplit = false;
698 return ret;
699 }
700
701 @Override
702 public boolean tryAdvance(Consumer<? super T> consumer) {
703 boolean hasNext;
704 if (beforeSplit) {
705 hasNext = aSpliterator.tryAdvance(consumer);
706 if (!hasNext) {
707 beforeSplit = false;
708 hasNext = bSpliterator.tryAdvance(consumer);
709 }
710 }
711 else
712 hasNext = bSpliterator.tryAdvance(consumer);
713 return hasNext;
714 }
715
716 @Override
717 public void forEachRemaining(Consumer<? super T> consumer) {
718 if (beforeSplit)
719 aSpliterator.forEachRemaining(consumer);
720 bSpliterator.forEachRemaining(consumer);
721 }
722
723 @Override
724 public long estimateSize() {
725 if (beforeSplit) {
726 // If one or both estimates are Long.MAX_VALUE then the sum
727 // will either be Long.MAX_VALUE or overflow to a negative value
728 long size = aSpliterator.estimateSize() + bSpliterator.estimateSize();
729 return (size >= 0) ? size : Long.MAX_VALUE;
730 }
731 else {
732 return bSpliterator.estimateSize();
733 }
734 }
735
736 @Override
737 public int characteristics() {
738 if (beforeSplit) {
739 // Concatenation loses DISTINCT and SORTED characteristics
740 return aSpliterator.characteristics() & bSpliterator.characteristics()
741 & ~(Spliterator.DISTINCT | Spliterator.SORTED
742 | (unsized ? Spliterator.SIZED | Spliterator.SUBSIZED : 0));
743 }
744 else {
745 return bSpliterator.characteristics();
746 }
747 }
748
749 @Override
750 public Comparator<? super T> getComparator() {
751 if (beforeSplit)
752 throw new IllegalStateException();
753 return bSpliterator.getComparator();
754 }
755
756 static class OfRef<T> extends ConcatSpliterator<T, Spliterator<T>> {
757 OfRef(Spliterator<T> aSpliterator, Spliterator<T> bSpliterator) {
758 super(aSpliterator, bSpliterator);
759 }
760 }
761
762 private static abstract class OfPrimitive<T, T_CONS, T_SPLITR extends Spliterator.OfPrimitive<T, T_CONS, T_SPLITR>>
763 extends ConcatSpliterator<T, T_SPLITR>
764 implements Spliterator.OfPrimitive<T, T_CONS, T_SPLITR> {
765 private OfPrimitive(T_SPLITR aSpliterator, T_SPLITR bSpliterator) {
766 super(aSpliterator, bSpliterator);
767 }
768
769 @Override
770 public boolean tryAdvance(T_CONS action) {
771 boolean hasNext;
772 if (beforeSplit) {
773 hasNext = aSpliterator.tryAdvance(action);
774 if (!hasNext) {
775 beforeSplit = false;
776 hasNext = bSpliterator.tryAdvance(action);
777 }
778 }
779 else
780 hasNext = bSpliterator.tryAdvance(action);
781 return hasNext;
782 }
783
784 @Override
785 public void forEachRemaining(T_CONS action) {
786 if (beforeSplit)
787 aSpliterator.forEachRemaining(action);
788 bSpliterator.forEachRemaining(action);
789 }
790 }
791
792 static class OfInt
793 extends ConcatSpliterator.OfPrimitive<Integer, IntConsumer, Spliterator.OfInt>
794 implements Spliterator.OfInt {
795 OfInt(Spliterator.OfInt aSpliterator, Spliterator.OfInt bSpliterator) {
796 super(aSpliterator, bSpliterator);
797 }
798 }
799
800 static class OfLong
801 extends ConcatSpliterator.OfPrimitive<Long, LongConsumer, Spliterator.OfLong>
802 implements Spliterator.OfLong {
803 OfLong(Spliterator.OfLong aSpliterator, Spliterator.OfLong bSpliterator) {
804 super(aSpliterator, bSpliterator);
805 }
806 }
807
808 static class OfDouble
809 extends ConcatSpliterator.OfPrimitive<Double, DoubleConsumer, Spliterator.OfDouble>
810 implements Spliterator.OfDouble {
811 OfDouble(Spliterator.OfDouble aSpliterator, Spliterator.OfDouble bSpliterator) {
812 super(aSpliterator, bSpliterator);
813 }
814 }
815 }
816 }
|