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.Objects; 28 import java.util.Spliterator; 29 import java.util.function.Supplier; 30 31 /** 32 * Low-level utility methods for creating and manipulating streams. 33 * 34 * <p>This class is mostly for library writers presenting stream views 35 * of data structures; most static stream methods intended for end users are in 36 * the various {@code Stream} classes. 37 * 38 * @since 1.8 39 */ 40 public final class StreamSupport { 41 42 // Suppresses default constructor, ensuring non-instantiability. StreamSupport()43 private StreamSupport() {} 44 45 /** 46 * Creates a new sequential or parallel {@code Stream} from a 47 * {@code Spliterator}. 48 * 49 * <p>The spliterator is only traversed, split, or queried for estimated 50 * size after the terminal operation of the stream pipeline commences. 51 * 52 * <p>It is strongly recommended the spliterator report a characteristic of 53 * {@code IMMUTABLE} or {@code CONCURRENT}, or be 54 * <a href="../Spliterator.html#binding">late-binding</a>. Otherwise, 55 * {@link #stream(java.util.function.Supplier, int, boolean)} should be used 56 * to reduce the scope of potential interference with the source. See 57 * <a href="package-summary.html#NonInterference">Non-Interference</a> for 58 * more details. 59 * 60 * @param <T> the type of stream elements 61 * @param spliterator a {@code Spliterator} describing the stream elements 62 * @param parallel if {@code true} then the returned stream is a parallel 63 * stream; if {@code false} the returned stream is a sequential 64 * stream. 65 * @return a new sequential or parallel {@code Stream} 66 */ stream(Spliterator<T> spliterator, boolean parallel)67 public static <T> Stream<T> stream(Spliterator<T> spliterator, boolean parallel) { 68 Objects.requireNonNull(spliterator); 69 return new ReferencePipeline.Head<>(spliterator, 70 StreamOpFlag.fromCharacteristics(spliterator), 71 parallel); 72 } 73 74 /** 75 * Creates a new sequential or parallel {@code Stream} from a 76 * {@code Supplier} of {@code Spliterator}. 77 * 78 * <p>The {@link Supplier#get()} method will be invoked on the supplier no 79 * more than once, and only after the terminal operation of the stream pipeline 80 * commences. 81 * 82 * <p>For spliterators that report a characteristic of {@code IMMUTABLE} 83 * or {@code CONCURRENT}, or that are 84 * <a href="../Spliterator.html#binding">late-binding</a>, it is likely 85 * more efficient to use {@link #stream(java.util.Spliterator, boolean)} 86 * instead. 87 * <p>The use of a {@code Supplier} in this form provides a level of 88 * indirection that reduces the scope of potential interference with the 89 * source. Since the supplier is only invoked after the terminal operation 90 * commences, any modifications to the source up to the start of the 91 * terminal operation are reflected in the stream result. See 92 * <a href="package-summary.html#NonInterference">Non-Interference</a> for 93 * more details. 94 * 95 * @param <T> the type of stream elements 96 * @param supplier a {@code Supplier} of a {@code Spliterator} 97 * @param characteristics Spliterator characteristics of the supplied 98 * {@code Spliterator}. The characteristics must be equal to 99 * {@code supplier.get().characteristics()}, otherwise undefined 100 * behavior may occur when terminal operation commences. 101 * @param parallel if {@code true} then the returned stream is a parallel 102 * stream; if {@code false} the returned stream is a sequential 103 * stream. 104 * @return a new sequential or parallel {@code Stream} 105 * @see #stream(java.util.Spliterator, boolean) 106 */ stream(Supplier<? extends Spliterator<T>> supplier, int characteristics, boolean parallel)107 public static <T> Stream<T> stream(Supplier<? extends Spliterator<T>> supplier, 108 int characteristics, 109 boolean parallel) { 110 Objects.requireNonNull(supplier); 111 return new ReferencePipeline.Head<>(supplier, 112 StreamOpFlag.fromCharacteristics(characteristics), 113 parallel); 114 } 115 116 /** 117 * Creates a new sequential or parallel {@code IntStream} from a 118 * {@code Spliterator.OfInt}. 119 * 120 * <p>The spliterator is only traversed, split, or queried for estimated size 121 * after the terminal operation of the stream pipeline commences. 122 * 123 * <p>It is strongly recommended the spliterator report a characteristic of 124 * {@code IMMUTABLE} or {@code CONCURRENT}, or be 125 * <a href="../Spliterator.html#binding">late-binding</a>. Otherwise, 126 * {@link #intStream(java.util.function.Supplier, int, boolean)} should be 127 * used to reduce the scope of potential interference with the source. See 128 * <a href="package-summary.html#NonInterference">Non-Interference</a> for 129 * more details. 130 * 131 * @param spliterator a {@code Spliterator.OfInt} describing the stream elements 132 * @param parallel if {@code true} then the returned stream is a parallel 133 * stream; if {@code false} the returned stream is a sequential 134 * stream. 135 * @return a new sequential or parallel {@code IntStream} 136 */ intStream(Spliterator.OfInt spliterator, boolean parallel)137 public static IntStream intStream(Spliterator.OfInt spliterator, boolean parallel) { 138 return new IntPipeline.Head<>(spliterator, 139 StreamOpFlag.fromCharacteristics(spliterator), 140 parallel); 141 } 142 143 /** 144 * Creates a new sequential or parallel {@code IntStream} from a 145 * {@code Supplier} of {@code Spliterator.OfInt}. 146 * 147 * <p>The {@link Supplier#get()} method will be invoked on the supplier no 148 * more than once, and only after the terminal operation of the stream pipeline 149 * commences. 150 * 151 * <p>For spliterators that report a characteristic of {@code IMMUTABLE} 152 * or {@code CONCURRENT}, or that are 153 * <a href="../Spliterator.html#binding">late-binding</a>, it is likely 154 * more efficient to use {@link #intStream(java.util.Spliterator.OfInt, boolean)} 155 * instead. 156 * <p>The use of a {@code Supplier} in this form provides a level of 157 * indirection that reduces the scope of potential interference with the 158 * source. Since the supplier is only invoked after the terminal operation 159 * commences, any modifications to the source up to the start of the 160 * terminal operation are reflected in the stream result. See 161 * <a href="package-summary.html#NonInterference">Non-Interference</a> for 162 * more details. 163 * 164 * @param supplier a {@code Supplier} of a {@code Spliterator.OfInt} 165 * @param characteristics Spliterator characteristics of the supplied 166 * {@code Spliterator.OfInt}. The characteristics must be equal to 167 * {@code supplier.get().characteristics()}, otherwise undefined 168 * behavior may occur when terminal operation commences. 169 * @param parallel if {@code true} then the returned stream is a parallel 170 * stream; if {@code false} the returned stream is a sequential 171 * stream. 172 * @return a new sequential or parallel {@code IntStream} 173 * @see #intStream(java.util.Spliterator.OfInt, boolean) 174 */ intStream(Supplier<? extends Spliterator.OfInt> supplier, int characteristics, boolean parallel)175 public static IntStream intStream(Supplier<? extends Spliterator.OfInt> supplier, 176 int characteristics, 177 boolean parallel) { 178 return new IntPipeline.Head<>(supplier, 179 StreamOpFlag.fromCharacteristics(characteristics), 180 parallel); 181 } 182 183 /** 184 * Creates a new sequential or parallel {@code LongStream} from a 185 * {@code Spliterator.OfLong}. 186 * 187 * <p>The spliterator is only traversed, split, or queried for estimated 188 * size after the terminal operation of the stream pipeline commences. 189 * 190 * <p>It is strongly recommended the spliterator report a characteristic of 191 * {@code IMMUTABLE} or {@code CONCURRENT}, or be 192 * <a href="../Spliterator.html#binding">late-binding</a>. Otherwise, 193 * {@link #longStream(java.util.function.Supplier, int, boolean)} should be 194 * used to reduce the scope of potential interference with the source. See 195 * <a href="package-summary.html#NonInterference">Non-Interference</a> for 196 * more details. 197 * 198 * @param spliterator a {@code Spliterator.OfLong} describing the stream elements 199 * @param parallel if {@code true} then the returned stream is a parallel 200 * stream; if {@code false} the returned stream is a sequential 201 * stream. 202 * @return a new sequential or parallel {@code LongStream} 203 */ longStream(Spliterator.OfLong spliterator, boolean parallel)204 public static LongStream longStream(Spliterator.OfLong spliterator, 205 boolean parallel) { 206 return new LongPipeline.Head<>(spliterator, 207 StreamOpFlag.fromCharacteristics(spliterator), 208 parallel); 209 } 210 211 /** 212 * Creates a new sequential or parallel {@code LongStream} from a 213 * {@code Supplier} of {@code Spliterator.OfLong}. 214 * 215 * <p>The {@link Supplier#get()} method will be invoked on the supplier no 216 * more than once, and only after the terminal operation of the stream pipeline 217 * commences. 218 * 219 * <p>For spliterators that report a characteristic of {@code IMMUTABLE} 220 * or {@code CONCURRENT}, or that are 221 * <a href="../Spliterator.html#binding">late-binding</a>, it is likely 222 * more efficient to use {@link #longStream(java.util.Spliterator.OfLong, boolean)} 223 * instead. 224 * <p>The use of a {@code Supplier} in this form provides a level of 225 * indirection that reduces the scope of potential interference with the 226 * source. Since the supplier is only invoked after the terminal operation 227 * commences, any modifications to the source up to the start of the 228 * terminal operation are reflected in the stream result. See 229 * <a href="package-summary.html#NonInterference">Non-Interference</a> for 230 * more details. 231 * 232 * @param supplier a {@code Supplier} of a {@code Spliterator.OfLong} 233 * @param characteristics Spliterator characteristics of the supplied 234 * {@code Spliterator.OfLong}. The characteristics must be equal to 235 * {@code supplier.get().characteristics()}, otherwise undefined 236 * behavior may occur when terminal operation commences. 237 * @param parallel if {@code true} then the returned stream is a parallel 238 * stream; if {@code false} the returned stream is a sequential 239 * stream. 240 * @return a new sequential or parallel {@code LongStream} 241 * @see #longStream(java.util.Spliterator.OfLong, boolean) 242 */ longStream(Supplier<? extends Spliterator.OfLong> supplier, int characteristics, boolean parallel)243 public static LongStream longStream(Supplier<? extends Spliterator.OfLong> supplier, 244 int characteristics, 245 boolean parallel) { 246 return new LongPipeline.Head<>(supplier, 247 StreamOpFlag.fromCharacteristics(characteristics), 248 parallel); 249 } 250 251 /** 252 * Creates a new sequential or parallel {@code DoubleStream} from a 253 * {@code Spliterator.OfDouble}. 254 * 255 * <p>The spliterator is only traversed, split, or queried for estimated size 256 * after the terminal operation of the stream pipeline commences. 257 * 258 * <p>It is strongly recommended the spliterator report a characteristic of 259 * {@code IMMUTABLE} or {@code CONCURRENT}, or be 260 * <a href="../Spliterator.html#binding">late-binding</a>. Otherwise, 261 * {@link #doubleStream(java.util.function.Supplier, int, boolean)} should 262 * be used to reduce the scope of potential interference with the source. See 263 * <a href="package-summary.html#NonInterference">Non-Interference</a> for 264 * more details. 265 * 266 * @param spliterator A {@code Spliterator.OfDouble} describing the stream elements 267 * @param parallel if {@code true} then the returned stream is a parallel 268 * stream; if {@code false} the returned stream is a sequential 269 * stream. 270 * @return a new sequential or parallel {@code DoubleStream} 271 */ doubleStream(Spliterator.OfDouble spliterator, boolean parallel)272 public static DoubleStream doubleStream(Spliterator.OfDouble spliterator, 273 boolean parallel) { 274 return new DoublePipeline.Head<>(spliterator, 275 StreamOpFlag.fromCharacteristics(spliterator), 276 parallel); 277 } 278 279 /** 280 * Creates a new sequential or parallel {@code DoubleStream} from a 281 * {@code Supplier} of {@code Spliterator.OfDouble}. 282 * 283 * <p>The {@link Supplier#get()} method will be invoked on the supplier no 284 * more than once, and only after the terminal operation of the stream pipeline 285 * commences. 286 * 287 * <p>For spliterators that report a characteristic of {@code IMMUTABLE} 288 * or {@code CONCURRENT}, or that are 289 * <a href="../Spliterator.html#binding">late-binding</a>, it is likely 290 * more efficient to use {@link #doubleStream(java.util.Spliterator.OfDouble, boolean)} 291 * instead. 292 * <p>The use of a {@code Supplier} in this form provides a level of 293 * indirection that reduces the scope of potential interference with the 294 * source. Since the supplier is only invoked after the terminal operation 295 * commences, any modifications to the source up to the start of the 296 * terminal operation are reflected in the stream result. See 297 * <a href="package-summary.html#NonInterference">Non-Interference</a> for 298 * more details. 299 * 300 * @param supplier A {@code Supplier} of a {@code Spliterator.OfDouble} 301 * @param characteristics Spliterator characteristics of the supplied 302 * {@code Spliterator.OfDouble}. The characteristics must be equal to 303 * {@code supplier.get().characteristics()}, otherwise undefined 304 * behavior may occur when terminal operation commences. 305 * @param parallel if {@code true} then the returned stream is a parallel 306 * stream; if {@code false} the returned stream is a sequential 307 * stream. 308 * @return a new sequential or parallel {@code DoubleStream} 309 * @see #doubleStream(java.util.Spliterator.OfDouble, boolean) 310 */ doubleStream(Supplier<? extends Spliterator.OfDouble> supplier, int characteristics, boolean parallel)311 public static DoubleStream doubleStream(Supplier<? extends Spliterator.OfDouble> supplier, 312 int characteristics, 313 boolean parallel) { 314 return new DoublePipeline.Head<>(supplier, 315 StreamOpFlag.fromCharacteristics(characteristics), 316 parallel); 317 } 318 } 319