StreamSupport.java revision ff18b5f136f92154f2e05217e3953d10f459e561
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 */
25package java.util.stream;
26
27import java.util.Objects;
28import java.util.Spliterator;
29import 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 */
40public 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}
319