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.
  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      */
  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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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 }