< prev index next >

src/java.base/share/classes/java/util/stream/LongStream.java

Print this page
rev 47861 : 8181175: Stream.concat behaves like terminal operation
Reviewed-by: smarks, briangoetz, dfuchs


1069             // Split the range in two and concatenate
1070             // Note: if the range is [Long.MIN_VALUE, Long.MAX_VALUE] then
1071             // the lower range, [Long.MIN_VALUE, 0), and upper range,
1072             // [0, Long.MAX_VALUE], will both be further split in two
1073             long m = startInclusive + Long.divideUnsigned(endInclusive - startInclusive, 2) + 1;
1074             return concat(range(startInclusive, m), rangeClosed(m, endInclusive));
1075         } else {
1076             return StreamSupport.longStream(
1077                     new Streams.RangeLongSpliterator(startInclusive, endInclusive, true), false);
1078         }
1079     }
1080 
1081     /**
1082      * Creates a lazily concatenated stream whose elements are all the
1083      * elements of the first stream followed by all the elements of the
1084      * second stream.  The resulting stream is ordered if both
1085      * of the input streams are ordered, and parallel if either of the input
1086      * streams is parallel.  When the resulting stream is closed, the close
1087      * handlers for both input streams are invoked.
1088      *




1089      * @implNote
1090      * Use caution when constructing streams from repeated concatenation.
1091      * Accessing an element of a deeply concatenated stream can result in deep
1092      * call chains, or even {@code StackOverflowError}.
1093      *












1094      * @param a the first stream
1095      * @param b the second stream
1096      * @return the concatenation of the two input streams
1097      */
1098     public static LongStream concat(LongStream a, LongStream b) {
1099         Objects.requireNonNull(a);
1100         Objects.requireNonNull(b);
1101 
1102         Spliterator.OfLong split = new Streams.ConcatSpliterator.OfLong(
1103                 a.spliterator(), b.spliterator());
1104         LongStream stream = StreamSupport.longStream(split, a.isParallel() || b.isParallel());
1105         return stream.onClose(Streams.composedClose(a, b));
1106     }
1107 
1108     /**
1109      * A mutable builder for a {@code LongStream}.
1110      *
1111      * <p>A stream builder has a lifecycle, which starts in a building
1112      * phase, during which elements can be added, and then transitions to a built
1113      * phase, after which elements may not be added.  The built phase begins




1069             // Split the range in two and concatenate
1070             // Note: if the range is [Long.MIN_VALUE, Long.MAX_VALUE] then
1071             // the lower range, [Long.MIN_VALUE, 0), and upper range,
1072             // [0, Long.MAX_VALUE], will both be further split in two
1073             long m = startInclusive + Long.divideUnsigned(endInclusive - startInclusive, 2) + 1;
1074             return concat(range(startInclusive, m), rangeClosed(m, endInclusive));
1075         } else {
1076             return StreamSupport.longStream(
1077                     new Streams.RangeLongSpliterator(startInclusive, endInclusive, true), false);
1078         }
1079     }
1080 
1081     /**
1082      * Creates a lazily concatenated stream whose elements are all the
1083      * elements of the first stream followed by all the elements of the
1084      * second stream.  The resulting stream is ordered if both
1085      * of the input streams are ordered, and parallel if either of the input
1086      * streams is parallel.  When the resulting stream is closed, the close
1087      * handlers for both input streams are invoked.
1088      *
1089      * <p>This method operates on the two input streams and binds each stream
1090      * to its source.  As a result subsequent modifications to an input stream
1091      * source may not be reflected in the concatenated stream result.
1092      *
1093      * @implNote
1094      * Use caution when constructing streams from repeated concatenation.
1095      * Accessing an element of a deeply concatenated stream can result in deep
1096      * call chains, or even {@code StackOverflowError}.
1097      *
1098      * @apiNote
1099      * To preserve optimization opportunities this method binds each stream to
1100      * its source and accepts only two streams as parameters.  For example, the
1101      * exact size of the concatenated stream source can be computed if the exact
1102      * size of each input stream source is known.
1103      * To concatenate more streams without binding, or without nested calls to
1104      * this method, try creating a stream of streams and flat-mapping with the
1105      * identity function, for example:
1106      * <pre>{@code
1107      *     LongStream concat = Stream.of(s1, s2, s3, s4).flatMapToLong(s -> s);
1108      * }</pre>
1109      *
1110      * @param a the first stream
1111      * @param b the second stream
1112      * @return the concatenation of the two input streams
1113      */
1114     public static LongStream concat(LongStream a, LongStream b) {
1115         Objects.requireNonNull(a);
1116         Objects.requireNonNull(b);
1117 
1118         Spliterator.OfLong split = new Streams.ConcatSpliterator.OfLong(
1119                 a.spliterator(), b.spliterator());
1120         LongStream stream = StreamSupport.longStream(split, a.isParallel() || b.isParallel());
1121         return stream.onClose(Streams.composedClose(a, b));
1122     }
1123 
1124     /**
1125      * A mutable builder for a {@code LongStream}.
1126      *
1127      * <p>A stream builder has a lifecycle, which starts in a building
1128      * phase, during which elements can be added, and then transitions to a built
1129      * phase, after which elements may not be added.  The built phase begins


< prev index next >