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