mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-18 06:15:16 +00:00
8011916: Spec update for java.util.stream
8024339: j.u.s.Stream.reduce(BinaryOperator) throws unexpected NPE Reviewed-by: mduigou
This commit is contained in:
parent
383970e790
commit
bef65e773f
@ -549,6 +549,7 @@ public interface Collection<E> extends Iterable<E> {
|
||||
* @return a {@code Spliterator} over the elements in this collection
|
||||
* @since 1.8
|
||||
*/
|
||||
@Override
|
||||
default Spliterator<E> spliterator() {
|
||||
return Spliterators.spliterator(this, 0);
|
||||
}
|
||||
|
||||
@ -105,5 +105,6 @@
|
||||
* </ul>
|
||||
*
|
||||
* @see java.lang.FunctionalInterface
|
||||
* @since 1.8
|
||||
*/
|
||||
package java.util.function;
|
||||
|
||||
@ -24,16 +24,103 @@
|
||||
*/
|
||||
package java.util.stream;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Spliterator;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.IntConsumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Base interface for stream types such as {@link Stream}, {@link IntStream},
|
||||
* etc. Contains methods common to all stream types.
|
||||
* A sequence of elements supporting sequential and parallel aggregate
|
||||
* operations. The following example illustrates an aggregate operation using
|
||||
* {@link Stream} and {@link IntStream}:
|
||||
*
|
||||
* @param <T> type of stream elements
|
||||
* @param <S> type of stream implementing {@code BaseStream}
|
||||
* <pre>{@code
|
||||
* int sum = widgets.stream()
|
||||
* .filter(w -> w.getColor() == RED)
|
||||
* .mapToInt(w -> w.getWeight())
|
||||
* .sum();
|
||||
* }</pre>
|
||||
*
|
||||
* In this example, {@code widgets} is a {@code Collection<Widget>}. We create
|
||||
* a stream of {@code Widget} objects via {@link Collection#stream Collection.stream()},
|
||||
* filter it to produce a stream containing only the red widgets, and then
|
||||
* transform it into a stream of {@code int} values representing the weight of
|
||||
* each red widget. Then this stream is summed to produce a total weight.
|
||||
*
|
||||
* <p>To perform a computation, stream
|
||||
* <a href="package-summary.html#StreamOps">operations</a> are composed into a
|
||||
* <em>stream pipeline</em>. A stream pipeline consists of a source (which
|
||||
* might be an array, a collection, a generator function, an IO channel,
|
||||
* etc), zero or more <em>intermediate operations</em> (which transform a
|
||||
* stream into another stream, such as {@link Stream#filter(Predicate)}), and a
|
||||
* <em>terminal operation</em> (which produces a result or side-effect, such
|
||||
* as {@link IntStream#sum()} or {@link IntStream#forEach(IntConsumer)}).
|
||||
* Streams are lazy; computation on the source data is only performed when the
|
||||
* terminal operation is initiated, and source elements are consumed only
|
||||
* as needed.
|
||||
*
|
||||
* <p>Collections and streams, while bearing some superficial similarities,
|
||||
* have different goals. Collections are primarily concerned with the efficient
|
||||
* management of, and access to, their elements. By contrast, streams do not
|
||||
* provide a means to directly access or manipulate their elements, and are
|
||||
* instead concerned with declaratively describing their source and the
|
||||
* computational operations which will be performed in aggregate on that source.
|
||||
* However, if the provided stream operations do not offer the desired
|
||||
* functionality, the {@link #iterator()} and {@link #spliterator()} operations
|
||||
* can be used to perform a controlled traversal.
|
||||
*
|
||||
* <p>A stream pipeline, like the "widgets" example above, can be viewed as
|
||||
* a <em>query</em> on the stream source. Unless the source was explicitly
|
||||
* designed for concurrent modification (such as a {@link ConcurrentHashMap}),
|
||||
* unpredictable or erroneous behavior may result from modifying the stream
|
||||
* source while it is being queried.
|
||||
*
|
||||
* <p>Most stream operations accept parameters that describe user-specified
|
||||
* behavior, such as the lambda expression {@code w -> w.getWeight()} passed to
|
||||
* {@code mapToInt} in the example above. Such parameters are always instances
|
||||
* of a <a href="../function/package-summary.html">functional interface</a> such
|
||||
* as {@link java.util.function.Function}, and are often lambda expressions or
|
||||
* method references. These parameters can never be null, should not modify the
|
||||
* stream source, and should be
|
||||
* <a href="package-summary.html#NonInterference">effectively stateless</a>
|
||||
* (their result should not depend on any state that might change during
|
||||
* execution of the stream pipeline.)
|
||||
*
|
||||
* <p>A stream should be operated on (invoking an intermediate or terminal stream
|
||||
* operation) only once. This rules out, for example, "forked" streams, where
|
||||
* the same source feeds two or more pipelines, or multiple traversals of the
|
||||
* same stream. A stream implementation may throw {@link IllegalStateException}
|
||||
* if it detects that the stream is being reused. However, since some stream
|
||||
* operations may return their receiver rather than a new stream object, it may
|
||||
* not be possible to detect reuse in all cases.
|
||||
*
|
||||
* <p>Streams have a {@link #close()} method and implement {@link AutoCloseable},
|
||||
* but nearly all stream instances do not actually need to be closed after use.
|
||||
* Generally, only streams whose source is an IO channel (such as those returned
|
||||
* by {@link Files#lines(Path, Charset)}) will require closing. Most streams
|
||||
* are backed by collections, arrays, or generating functions, which require no
|
||||
* special resource management. (If a stream does require closing, it can be
|
||||
* declared as a resource in a {@code try}-with-resources statement.)
|
||||
*
|
||||
* <p>Stream pipelines may execute either sequentially or in
|
||||
* <a href="package-summary.html#Parallelism">parallel</a>. This
|
||||
* execution mode is a property of the stream. Streams are created
|
||||
* with an initial choice of sequential or parallel execution. (For example,
|
||||
* {@link Collection#stream() Collection.stream()} creates a sequential stream,
|
||||
* and {@link Collection#parallelStream() Collection.parallelStream()} creates
|
||||
* a parallel one.) This choice of execution mode may be modified by the
|
||||
* {@link #sequential()} or {@link #parallel()} methods, and may be queried with
|
||||
* the {@link #isParallel()} method.
|
||||
*
|
||||
* @param <T> the type of the stream elements
|
||||
* @param <S> the type of of the stream implementing {@code BaseStream}
|
||||
* @since 1.8
|
||||
* @see <a href="package-summary.html">java.util.stream</a>
|
||||
*/
|
||||
public interface BaseStream<T, S extends BaseStream<T, S>>
|
||||
extends AutoCloseable {
|
||||
@ -58,14 +145,11 @@ public interface BaseStream<T, S extends BaseStream<T, S>>
|
||||
Spliterator<T> spliterator();
|
||||
|
||||
/**
|
||||
* Returns whether this stream, when executed, would execute in parallel
|
||||
* (assuming no further modification of the stream, such as appending
|
||||
* further intermediate operations or changing its parallelism). Calling
|
||||
* this method after invoking an intermediate or terminal stream operation
|
||||
* method may yield unpredictable results.
|
||||
* Returns whether this stream, if a terminal operation were to be executed,
|
||||
* would execute in parallel. Calling this method after invoking an
|
||||
* terminal stream operation method may yield unpredictable results.
|
||||
*
|
||||
* @return {@code true} if this stream would execute in parallel if executed
|
||||
* without further modification otherwise {@code false}
|
||||
*/
|
||||
boolean isParallel();
|
||||
|
||||
@ -96,7 +180,8 @@ public interface BaseStream<T, S extends BaseStream<T, S>>
|
||||
/**
|
||||
* Returns an equivalent stream that is
|
||||
* <a href="package-summary.html#Ordering">unordered</a>. May return
|
||||
* itself if the stream was already unordered.
|
||||
* itself, either because the stream was already unordered, or because
|
||||
* the underlying stream state was modified to be unordered.
|
||||
*
|
||||
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
|
||||
* operation</a>.
|
||||
|
||||
@ -26,6 +26,7 @@ package java.util.stream;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BinaryOperator;
|
||||
@ -33,71 +34,74 @@ import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* A <a href="package-summary.html#Reduction">reduction operation</a> that
|
||||
* folds input elements into a mutable result container, optionally transforming
|
||||
* A <a href="package-summary.html#Reduction">mutable reduction operation</a> that
|
||||
* accumulates input elements into a mutable result container, optionally transforming
|
||||
* the accumulated result into a final representation after all input elements
|
||||
* have been processed.
|
||||
* have been processed. Reduction operations can be performed either sequentially
|
||||
* or in parallel.
|
||||
*
|
||||
* <p>Examples of mutable reduction operations include:
|
||||
* accumulating elements into a {@code Collection}; concatenating
|
||||
* strings using a {@code StringBuilder}; computing summary information about
|
||||
* elements such as sum, min, max, or average; computing "pivot table" summaries
|
||||
* such as "maximum valued transaction by seller", etc. Reduction operations
|
||||
* can be performed either sequentially or in parallel.
|
||||
*
|
||||
* <p>The following are examples of using the predefined {@code Collector}
|
||||
* implementations in {@link Collectors} with the {@code Stream} API to perform
|
||||
* mutable reduction tasks:
|
||||
* <pre>{@code
|
||||
* // Accumulate names into a List
|
||||
* List<String> list = people.stream().map(Person::getName).collect(Collectors.toList());
|
||||
*
|
||||
* // Accumulate names into a TreeSet
|
||||
* Set<String> list = people.stream().map(Person::getName).collect(Collectors.toCollection(TreeSet::new));
|
||||
*
|
||||
* // Convert elements to strings and concatenate them, separated by commas
|
||||
* String joined = things.stream()
|
||||
* .map(Object::toString)
|
||||
* .collect(Collectors.joining(", "));
|
||||
*
|
||||
* // Find highest-paid employee
|
||||
* Employee highestPaid = employees.stream()
|
||||
* .collect(Collectors.maxBy(Comparators.comparing(Employee::getSalary)))
|
||||
* .get();
|
||||
*
|
||||
* // Group employees by department
|
||||
* Map<Department, List<Employee>> byDept
|
||||
* = employees.stream()
|
||||
* .collect(Collectors.groupingBy(Employee::getDepartment));
|
||||
*
|
||||
* // Find highest-paid employee by department
|
||||
* Map<Department, Optional<Employee>> highestPaidByDept
|
||||
* = employees.stream()
|
||||
* .collect(Collectors.groupingBy(Employee::getDepartment,
|
||||
* Collectors.maxBy(Comparators.comparing(Employee::getSalary))));
|
||||
*
|
||||
* // Partition students into passing and failing
|
||||
* Map<Boolean, List<Student>> passingFailing =
|
||||
* students.stream()
|
||||
* .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));
|
||||
*
|
||||
* }</pre>
|
||||
* such as "maximum valued transaction by seller", etc. The class {@link Collectors}
|
||||
* provides implementations of many common mutable reductions.
|
||||
*
|
||||
* <p>A {@code Collector} is specified by four functions that work together to
|
||||
* accumulate entries into a mutable result container, and optionally perform
|
||||
* a final transform on the result. They are: creation of a new result container,
|
||||
* incorporating a new data element into a result container, combining two
|
||||
* result containers into one, and performing a final transform on the container.
|
||||
* The combiner function is used during parallel operations, where
|
||||
* subsets of the input are accumulated into separate result
|
||||
* containers, and then the subresults merged into a combined result. The
|
||||
* combiner function may merge one set of subresults into the other and return
|
||||
* that, or it may return a new object to describe the combined results.
|
||||
* a final transform on the result. They are: <ul>
|
||||
* <li>creation of a new result container ({@link #supplier()})</li>
|
||||
* <li>incorporating a new data element into a result container ({@link #accumulator()})</li>
|
||||
* <li>combining two result containers into one ({@link #combiner()})</li>
|
||||
* <li>performing an optional final transform on the container ({@link #finisher()})</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>Collectors also have a set of characteristics, such as
|
||||
* {@link Characteristics#CONCURRENT}. These characteristics provide
|
||||
* hints that can be used by a reduction implementation to provide better
|
||||
* performance.
|
||||
* {@link Characteristics#CONCURRENT}, that provide hints that can be used by a
|
||||
* reduction implementation to provide better performance.
|
||||
*
|
||||
* <p>A sequential implementation of a reduction using a collector would
|
||||
* create a single result container using the supplier function, and invoke the
|
||||
* accumulator function once for each input element. A parallel implementation
|
||||
* would partition the input, create a result container for each partition,
|
||||
* accumulate the contents of each partition into a subresult for that partition,
|
||||
* and then use the combiner function to merge the subresults into a combined
|
||||
* result.
|
||||
*
|
||||
* <p>To ensure that sequential and parallel executions produce equivalent
|
||||
* results, the collector functions must satisfy an <em>identity</em> and an
|
||||
* <a href="package-summary.html#Associativity">associativity</a> constraints.
|
||||
*
|
||||
* <p>The identity constraint says that for any partially accumulated result,
|
||||
* combining it with an empty result container must produce an equivalent
|
||||
* result. That is, for a partially accumulated result {@code a} that is the
|
||||
* result of any series of accumulator and combiner invocations, {@code a} must
|
||||
* be equivalent to {@code combiner.apply(a, supplier.get())}.
|
||||
*
|
||||
* <p>The associativity constraint says that splitting the computation must
|
||||
* produce an equivalent result. That is, for any input elements {@code t1}
|
||||
* and {@code t2}, the results {@code r1} and {@code r2} in the computation
|
||||
* below must be equivalent:
|
||||
* <pre>{@code
|
||||
* A a1 = supplier.get();
|
||||
* accumulator.accept(a1, t1);
|
||||
* accumulator.accept(a1, t2);
|
||||
* R r1 = finisher.apply(a1); // result without splitting
|
||||
*
|
||||
* A a2 = supplier.get();
|
||||
* accumulator.accept(a2, t1);
|
||||
* A a3 = supplier.get();
|
||||
* accumulator.accept(a3, t2);
|
||||
* R r2 = finisher.apply(combiner.apply(a2, a3)); // result with splitting
|
||||
* } </pre>
|
||||
*
|
||||
* <p>For collectors that do not have the {@code UNORDERED} characteristic,
|
||||
* two accumulated results {@code a1} and {@code a2} are equivalent if
|
||||
* {@code finisher.apply(a1).equals(finisher.apply(a2))}. For unordered
|
||||
* collectors, equivalence is relaxed to allow for non-equality related to
|
||||
* differences in order. (For example, an unordered collector that accumulated
|
||||
* elements to a {@code List} would consider two lists equivalent if they
|
||||
* contained the same elements, ignoring order.)
|
||||
*
|
||||
* <p>Libraries that implement reduction based on {@code Collector}, such as
|
||||
* {@link Stream#collect(Collector)}, must adhere to the following constraints:
|
||||
@ -132,6 +136,20 @@ import java.util.function.Supplier;
|
||||
* originating data is unordered.</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>In addition to the predefined implementations in {@link Collectors}, the
|
||||
* static factory methods {@link #of(Supplier, BiConsumer, BinaryOperator, Characteristics...)}
|
||||
* can be used to construct collectors. For example, you could create a collector
|
||||
* that accumulates widgets into a {@code TreeSet} with:
|
||||
*
|
||||
* <pre>{@code
|
||||
* Collector<Widget, ?, TreeSet<Widget>> intoSet =
|
||||
* Collector.of(TreeSet::new, TreeSet::add,
|
||||
* (left, right) -> { left.addAll(right); return left; });
|
||||
* }</pre>
|
||||
*
|
||||
* (This behavior is also implemented by the predefined collector
|
||||
* {@link Collectors#toCollection(Supplier)}).
|
||||
*
|
||||
* @apiNote
|
||||
* Performing a reduction operation with a {@code Collector} should produce a
|
||||
* result equivalent to:
|
||||
@ -144,27 +162,35 @@ import java.util.function.Supplier;
|
||||
*
|
||||
* <p>However, the library is free to partition the input, perform the reduction
|
||||
* on the partitions, and then use the combiner function to combine the partial
|
||||
* results to achieve a parallel reduction. Depending on the specific reduction
|
||||
* results to achieve a parallel reduction. (Depending on the specific reduction
|
||||
* operation, this may perform better or worse, depending on the relative cost
|
||||
* of the accumulator and combiner functions.
|
||||
* of the accumulator and combiner functions.)
|
||||
*
|
||||
* <p>An example of an operation that can be easily modeled by {@code Collector}
|
||||
* is accumulating elements into a {@code TreeSet}. In this case, the {@code
|
||||
* resultSupplier()} function is {@code () -> new Treeset<T>()}, the
|
||||
* {@code accumulator} function is
|
||||
* {@code (set, element) -> set.add(element) }, and the combiner
|
||||
* function is {@code (left, right) -> { left.addAll(right); return left; }}.
|
||||
* (This behavior is implemented by
|
||||
* {@code Collectors.toCollection(TreeSet::new)}).
|
||||
* <p>Collectors are designed to be <em>composed</em>; many of the methods
|
||||
* in {@link Collectors} are functions that take a collector and produce
|
||||
* a new collector. For example, given the following collector that computes
|
||||
* the sum of the salaries of a stream of employees:
|
||||
*
|
||||
* TODO Associativity and commutativity
|
||||
* <pre>{@code
|
||||
* Collector<Employee, ?, Integer> summingSalaries
|
||||
* = Collectors.summingInt(Employee::getSalary))
|
||||
* }</pre>
|
||||
*
|
||||
* If we wanted to create a collector to tabulate the sum of salaries by
|
||||
* department, we could reuse the "sum of salaries" logic using
|
||||
* {@link Collectors#groupingBy(Function, Collector)}:
|
||||
*
|
||||
* <pre>{@code
|
||||
* Collector<Employee, ?, Map<Department, Integer>> summingSalariesByDept
|
||||
* = Collectors.groupingBy(Employee::getDepartment, summingSalaries);
|
||||
* }</pre>
|
||||
*
|
||||
* @see Stream#collect(Collector)
|
||||
* @see Collectors
|
||||
*
|
||||
* @param <T> the type of input elements to the reduction operation
|
||||
* @param <A> the mutable accumulation type of the reduction operation (often
|
||||
* hidden as an implementation detail)
|
||||
* hidden as an implementation detail)
|
||||
* @param <R> the result type of the reduction operation
|
||||
* @since 1.8
|
||||
*/
|
||||
@ -177,25 +203,25 @@ public interface Collector<T, A, R> {
|
||||
Supplier<A> supplier();
|
||||
|
||||
/**
|
||||
* A function that folds a new value into a mutable result container.
|
||||
* A function that folds a value into a mutable result container.
|
||||
*
|
||||
* @return a function which folds a new value into a mutable result container
|
||||
* @return a function which folds a value into a mutable result container
|
||||
*/
|
||||
BiConsumer<A, T> accumulator();
|
||||
|
||||
/**
|
||||
* A function that accepts two partial results and merges them. The
|
||||
* combiner function may fold state from one argument into the other and
|
||||
* return that, or may return a new result object.
|
||||
* return that, or may return a new result container.
|
||||
*
|
||||
* @return a function which combines two partial results into a cumulative
|
||||
* @return a function which combines two partial results into a combined
|
||||
* result
|
||||
*/
|
||||
BinaryOperator<A> combiner();
|
||||
|
||||
/**
|
||||
* Perform the final transformation from the intermediate accumulation type
|
||||
* {@code A} to the final result representation {@code R}.
|
||||
* {@code A} to the final result type {@code R}.
|
||||
*
|
||||
* <p>If the characteristic {@code IDENTITY_TRANSFORM} is
|
||||
* set, this function may be presumed to be an identity transform with an
|
||||
@ -228,12 +254,17 @@ public interface Collector<T, A, R> {
|
||||
* @param <T> The type of input elements for the new collector
|
||||
* @param <R> The type of intermediate accumulation result, and final result,
|
||||
* for the new collector
|
||||
* @throws NullPointerException if any argument is null
|
||||
* @return the new {@code Collector}
|
||||
*/
|
||||
public static<T, R> Collector<T, R, R> of(Supplier<R> supplier,
|
||||
BiConsumer<R, T> accumulator,
|
||||
BinaryOperator<R> combiner,
|
||||
Characteristics... characteristics) {
|
||||
Objects.requireNonNull(supplier);
|
||||
Objects.requireNonNull(accumulator);
|
||||
Objects.requireNonNull(combiner);
|
||||
Objects.requireNonNull(characteristics);
|
||||
Set<Characteristics> cs = (characteristics.length == 0)
|
||||
? Collectors.CH_ID
|
||||
: Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH,
|
||||
@ -254,6 +285,7 @@ public interface Collector<T, A, R> {
|
||||
* @param <T> The type of input elements for the new collector
|
||||
* @param <A> The intermediate accumulation type of the new collector
|
||||
* @param <R> The final result type of the new collector
|
||||
* @throws NullPointerException if any argument is null
|
||||
* @return the new {@code Collector}
|
||||
*/
|
||||
public static<T, A, R> Collector<T, A, R> of(Supplier<A> supplier,
|
||||
@ -261,6 +293,11 @@ public interface Collector<T, A, R> {
|
||||
BinaryOperator<A> combiner,
|
||||
Function<A, R> finisher,
|
||||
Characteristics... characteristics) {
|
||||
Objects.requireNonNull(supplier);
|
||||
Objects.requireNonNull(accumulator);
|
||||
Objects.requireNonNull(combiner);
|
||||
Objects.requireNonNull(finisher);
|
||||
Objects.requireNonNull(characteristics);
|
||||
Set<Characteristics> cs = Collectors.CH_NOID;
|
||||
if (characteristics.length > 0) {
|
||||
cs = EnumSet.noneOf(Characteristics.class);
|
||||
@ -288,8 +325,9 @@ public interface Collector<T, A, R> {
|
||||
CONCURRENT,
|
||||
|
||||
/**
|
||||
* Indicates that the result container has no intrinsic order, such as
|
||||
* a {@link Set}.
|
||||
* Indicates that the collection operation does not commit to preserving
|
||||
* the encounter order of input elements. (This might be true if the
|
||||
* result container has no intrinsic order, such as a {@link Set}.)
|
||||
*/
|
||||
UNORDERED,
|
||||
|
||||
|
||||
@ -62,37 +62,35 @@ import java.util.function.ToLongFunction;
|
||||
* operations, such as accumulating elements into collections, summarizing
|
||||
* elements according to various criteria, etc.
|
||||
*
|
||||
* <p>The following are examples of using the predefined {@code Collector}
|
||||
* implementations in {@link Collectors} with the {@code Stream} API to perform
|
||||
* mutable reduction tasks:
|
||||
* <p>The following are examples of using the predefined collectors to perform
|
||||
* common mutable reduction tasks:
|
||||
*
|
||||
* <pre>{@code
|
||||
* // Accumulate names into a List
|
||||
* List<String> list = people.stream().map(Person::getName).collect(Collectors.toList());
|
||||
*
|
||||
* // Accumulate names into a TreeSet
|
||||
* Set<String> list = people.stream().map(Person::getName).collect(Collectors.toCollection(TreeSet::new));
|
||||
* Set<String> set = people.stream().map(Person::getName).collect(Collectors.toCollection(TreeSet::new));
|
||||
*
|
||||
* // Convert elements to strings and concatenate them, separated by commas
|
||||
* String joined = things.stream()
|
||||
* .map(Object::toString)
|
||||
* .collect(Collectors.joining(", "));
|
||||
*
|
||||
* // Find highest-paid employee
|
||||
* Employee highestPaid = employees.stream()
|
||||
* .collect(Collectors.maxBy(Comparator.comparing(Employee::getSalary)))
|
||||
* .get();
|
||||
* // Compute sum of salaries of employee
|
||||
* int total = employees.stream()
|
||||
* .collect(Collectors.summingInt(Employee::getSalary)));
|
||||
*
|
||||
* // Group employees by department
|
||||
* Map<Department, List<Employee>> byDept
|
||||
* = employees.stream()
|
||||
* .collect(Collectors.groupingBy(Employee::getDepartment));
|
||||
*
|
||||
* // Find highest-paid employee by department
|
||||
* Map<Department, Optional<Employee>> highestPaidByDept
|
||||
* // Compute sum of salaries by department
|
||||
* Map<Department, Integer> totalByDept
|
||||
* = employees.stream()
|
||||
* .collect(Collectors.groupingBy(Employee::getDepartment,
|
||||
* Collectors.maxBy(Comparator.comparing(Employee::getSalary))));
|
||||
* Collectors.summingInt(Employee::getSalary)));
|
||||
*
|
||||
* // Partition students into passing and failing
|
||||
* Map<Boolean, List<Student>> passingFailing =
|
||||
@ -101,8 +99,6 @@ import java.util.function.ToLongFunction;
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* TODO explanation of parallel collection
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public final class Collectors {
|
||||
@ -222,7 +218,8 @@ public final class Collectors {
|
||||
/**
|
||||
* Returns a {@code Collector} that accumulates the input elements into a
|
||||
* new {@code List}. There are no guarantees on the type, mutability,
|
||||
* serializability, or thread-safety of the {@code List} returned.
|
||||
* serializability, or thread-safety of the {@code List} returned; if more
|
||||
* control over the returned {@code List} is required, use {@link #toCollection(Supplier)}.
|
||||
*
|
||||
* @param <T> the type of the input elements
|
||||
* @return a {@code Collector} which collects all the input elements into a
|
||||
@ -238,7 +235,9 @@ public final class Collectors {
|
||||
/**
|
||||
* Returns a {@code Collector} that accumulates the input elements into a
|
||||
* new {@code Set}. There are no guarantees on the type, mutability,
|
||||
* serializability, or thread-safety of the {@code Set} returned.
|
||||
* serializability, or thread-safety of the {@code Set} returned; if more
|
||||
* control over the returned {@code Set} is required, use
|
||||
* {@link #toCollection(Supplier)}.
|
||||
*
|
||||
* <p>This is an {@link Collector.Characteristics#UNORDERED unordered}
|
||||
* Collector.
|
||||
@ -903,7 +902,7 @@ public final class Collectors {
|
||||
* where the city names are sorted:
|
||||
* <pre>{@code
|
||||
* ConcurrentMap<City, Set<String>> namesByCity
|
||||
* = people.stream().collect(groupingByConcurrent(Person::getCity, ConcurrentSkipListMap::new,
|
||||
* = people.stream().collect(groupingByConcurrent(Person::getCity,
|
||||
* mapping(Person::getLastName, toSet())));
|
||||
* }</pre>
|
||||
*
|
||||
|
||||
@ -313,8 +313,8 @@ abstract class DoublePipeline<E_IN>
|
||||
}
|
||||
|
||||
@Override
|
||||
public final DoubleStream peek(DoubleConsumer consumer) {
|
||||
Objects.requireNonNull(consumer);
|
||||
public final DoubleStream peek(DoubleConsumer action) {
|
||||
Objects.requireNonNull(action);
|
||||
return new StatelessOp<Double>(this, StreamShape.DOUBLE_VALUE,
|
||||
0) {
|
||||
@Override
|
||||
@ -322,7 +322,7 @@ abstract class DoublePipeline<E_IN>
|
||||
return new Sink.ChainedDouble<Double>(sink) {
|
||||
@Override
|
||||
public void accept(double t) {
|
||||
consumer.accept(t);
|
||||
action.accept(t);
|
||||
downstream.accept(t);
|
||||
}
|
||||
};
|
||||
@ -436,14 +436,14 @@ abstract class DoublePipeline<E_IN>
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <R> R collect(Supplier<R> resultFactory,
|
||||
public final <R> R collect(Supplier<R> supplier,
|
||||
ObjDoubleConsumer<R> accumulator,
|
||||
BiConsumer<R, R> combiner) {
|
||||
BinaryOperator<R> operator = (left, right) -> {
|
||||
combiner.accept(left, right);
|
||||
return left;
|
||||
};
|
||||
return evaluate(ReduceOps.makeDouble(resultFactory, accumulator, operator));
|
||||
return evaluate(ReduceOps.makeDouble(supplier, accumulator, operator));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -24,13 +24,18 @@
|
||||
*/
|
||||
package java.util.stream;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.DoubleSummaryStatistics;
|
||||
import java.util.Objects;
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.PrimitiveIterator;
|
||||
import java.util.Spliterator;
|
||||
import java.util.Spliterators;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.DoubleBinaryOperator;
|
||||
import java.util.function.DoubleConsumer;
|
||||
@ -45,40 +50,87 @@ import java.util.function.ObjDoubleConsumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* A sequence of primitive double elements supporting sequential and parallel
|
||||
* bulk operations. Streams support lazy intermediate operations (transforming
|
||||
* a stream to another stream) such as {@code filter} and {@code map}, and terminal
|
||||
* operations (consuming the contents of a stream to produce a result or
|
||||
* side-effect), such as {@code forEach}, {@code findFirst}, and {@code
|
||||
* iterator}. Once an operation has been performed on a stream, it
|
||||
* is considered <em>consumed</em> and no longer usable for other operations.
|
||||
* A sequence of elements supporting sequential and parallel aggregate
|
||||
* operations. The following example illustrates an aggregate operation using
|
||||
* {@link Stream} and {@link DoubleStream}:
|
||||
*
|
||||
* <p>For sequential stream pipelines, all operations are performed in the
|
||||
* <a href="package-summary.html#Ordering">encounter order</a> of the pipeline
|
||||
* source, if the pipeline source has a defined encounter order.
|
||||
* <pre>{@code
|
||||
* double sum = widgets.stream()
|
||||
* .filter(w -> w.getColor() == RED)
|
||||
* .mapToDouble(w -> w.getWeight())
|
||||
* .sum();
|
||||
* }</pre>
|
||||
*
|
||||
* <p>For parallel stream pipelines, unless otherwise specified, intermediate
|
||||
* stream operations preserve the <a href="package-summary.html#Ordering">
|
||||
* encounter order</a> of their source, and terminal operations
|
||||
* respect the encounter order of their source, if the source
|
||||
* has an encounter order. Provided that and parameters to stream operations
|
||||
* satisfy the <a href="package-summary.html#NonInterference">non-interference
|
||||
* requirements</a>, and excepting differences arising from the absence of
|
||||
* a defined encounter order, the result of a stream pipeline should be the
|
||||
* stable across multiple executions of the same operations on the same source.
|
||||
* However, the timing and thread in which side-effects occur (for those
|
||||
* operations which are allowed to produce side-effects, such as
|
||||
* {@link #forEach(DoubleConsumer)}), are explicitly nondeterministic for parallel
|
||||
* execution of stream pipelines.
|
||||
* In this example, {@code widgets} is a {@code Collection<Widget>}. We create
|
||||
* a stream of {@code Widget} objects via {@link Collection#stream Collection.stream()},
|
||||
* filter it to produce a stream containing only the red widgets, and then
|
||||
* transform it into a stream of {@code double} values representing the weight of
|
||||
* each red widget. Then this stream is summed to produce a total weight.
|
||||
*
|
||||
* <p>Unless otherwise noted, passing a {@code null} argument to any stream
|
||||
* method may result in a {@link NullPointerException}.
|
||||
* <p>To perform a computation, stream
|
||||
* <a href="package-summary.html#StreamOps">operations</a> are composed into a
|
||||
* <em>stream pipeline</em>. A stream pipeline consists of a source (which
|
||||
* might be an array, a collection, a generator function, an IO channel,
|
||||
* etc), zero or more <em>intermediate operations</em> (which transform a
|
||||
* stream into another stream, such as {@link DoubleStream#filter(DoublePredicate)}), and a
|
||||
* <em>terminal operation</em> (which produces a result or side-effect, such
|
||||
* as {@link DoubleStream#sum()} or {@link DoubleStream#forEach(DoubleConsumer)}.
|
||||
* Streams are lazy; computation on the source data is only performed when the
|
||||
* terminal operation is initiated, and source elements are consumed only
|
||||
* as needed.
|
||||
*
|
||||
* @apiNote
|
||||
* Streams are not data structures; they do not manage the storage for their
|
||||
* elements, nor do they support access to individual elements. However,
|
||||
* you can use the {@link #iterator()} or {@link #spliterator()} operations to
|
||||
* perform a controlled traversal.
|
||||
* <p>Collections and streams, while bearing some superficial similarities,
|
||||
* have different goals. Collections are primarily concerned with the efficient
|
||||
* management of, and access to, their elements. By contrast, streams do not
|
||||
* provide a means to directly access or manipulate their elements, and are
|
||||
* instead concerned with declaratively describing their source and the
|
||||
* computational operations which will be performed in aggregate on that source.
|
||||
* However, if the provided stream operations do not offer the desired
|
||||
* functionality, the {@link #iterator()} and {@link #spliterator()} operations
|
||||
* can be used to perform a controlled traversal.
|
||||
*
|
||||
* <p>A stream pipeline, like the "widgets" example above, can be viewed as
|
||||
* a <em>query</em> on the stream source. Unless the source was explicitly
|
||||
* designed for concurrent modification (such as a {@link ConcurrentHashMap}),
|
||||
* unpredictable or erroneous behavior may result from modifying the stream
|
||||
* source while it is being queried.
|
||||
*
|
||||
* <p>Most stream operations accept parameters that describe user-specified
|
||||
* behavior, such as the lambda expression {@code w -> w.getWeight()} passed to
|
||||
* {@code mapToDouble} in the example above. Such parameters are always instances
|
||||
* of a <a href="../function/package-summary.html">functional interface</a> such
|
||||
* as {@link java.util.function.Function}, and are often lambda expressions or
|
||||
* method references. These parameters can never be null, should not modify the
|
||||
* stream source, and should be
|
||||
* <a href="package-summary.html#NonInterference">effectively stateless</a>
|
||||
* (their result should not depend on any state that might change during
|
||||
* execution of the stream pipeline.)
|
||||
*
|
||||
* <p>A stream should be operated on (invoking an intermediate or terminal stream
|
||||
* operation) only once. This rules out, for example, "forked" streams, where
|
||||
* the same source feeds two or more pipelines, or multiple traversals of the
|
||||
* same stream. A stream implementation may throw {@link IllegalStateException}
|
||||
* if it detects that the stream is being reused. However, since some stream
|
||||
* operations may return their receiver rather than a new stream object, it may
|
||||
* not be possible to detect reuse in all cases.
|
||||
*
|
||||
* <p>Streams have a {@link #close()} method and implement {@link AutoCloseable},
|
||||
* but nearly all stream instances do not actually need to be closed after use.
|
||||
* Generally, only streams whose source is an IO channel (such as those returned
|
||||
* by {@link Files#lines(Path, Charset)}) will require closing. Most streams
|
||||
* are backed by collections, arrays, or generating functions, which require no
|
||||
* special resource management. (If a stream does require closing, it can be
|
||||
* declared as a resource in a {@code try}-with-resources statement.)
|
||||
*
|
||||
* <p>Stream pipelines may execute either sequentially or in
|
||||
* <a href="package-summary.html#Parallelism">parallel</a>. This
|
||||
* execution mode is a property of the stream. Streams are created
|
||||
* with an initial choice of sequential or parallel execution. (For example,
|
||||
* {@link Collection#stream() Collection.stream()} creates a sequential stream,
|
||||
* and {@link Collection#parallelStream() Collection.parallelStream()} creates
|
||||
* a parallel one.) This choice of execution mode may be modified by the
|
||||
* {@link #sequential()} or {@link #parallel()} methods, and may be queried with
|
||||
* the {@link #isParallel()} method.
|
||||
*
|
||||
* @since 1.8
|
||||
* @see <a href="package-summary.html">java.util.stream</a>
|
||||
@ -159,22 +211,13 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
|
||||
/**
|
||||
* Returns a stream consisting of the results of replacing each element of
|
||||
* this stream with the contents of the stream produced by applying the
|
||||
* provided mapping function to each element.
|
||||
* provided mapping function to each element. (If the result of the mapping
|
||||
* function is {@code null}, this is treated as if the result was an empty
|
||||
* stream.)
|
||||
*
|
||||
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
|
||||
* operation</a>.
|
||||
*
|
||||
* @apiNote
|
||||
* The {@code flatMap()} operation has the effect of applying a one-to-many
|
||||
* tranformation to the elements of the stream, and then flattening the
|
||||
* resulting elements into a new stream. For example, if {@code orders}
|
||||
* is a stream of purchase orders, and each purchase order contains a
|
||||
* collection of line items, then the following produces a stream of line
|
||||
* items:
|
||||
* <pre>{@code
|
||||
* orderStream.flatMap(order -> order.getLineItems().stream())...
|
||||
* }</pre>
|
||||
*
|
||||
* @param mapper a <a href="package-summary.html#NonInterference">
|
||||
* non-interfering, stateless</a> function to apply to
|
||||
* each element which produces an {@code DoubleStream} of new
|
||||
@ -226,18 +269,18 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
|
||||
* <pre>{@code
|
||||
* list.stream()
|
||||
* .filter(filteringFunction)
|
||||
* .peek(e -> {System.out.println("Filtered value: " + e); });
|
||||
* .peek(e -> System.out.println("Filtered value: " + e));
|
||||
* .map(mappingFunction)
|
||||
* .peek(e -> {System.out.println("Mapped value: " + e); });
|
||||
* .peek(e -> System.out.println("Mapped value: " + e));
|
||||
* .collect(Collectors.toDoubleSummaryStastistics());
|
||||
* }</pre>
|
||||
*
|
||||
* @param consumer a <a href="package-summary.html#NonInterference">
|
||||
* @param action a <a href="package-summary.html#NonInterference">
|
||||
* non-interfering</a> action to perform on the elements as
|
||||
* they are consumed from the stream
|
||||
* @return the new stream
|
||||
*/
|
||||
DoubleStream peek(DoubleConsumer consumer);
|
||||
DoubleStream peek(DoubleConsumer action);
|
||||
|
||||
/**
|
||||
* Returns a stream consisting of the elements of this stream, truncated
|
||||
@ -254,8 +297,8 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
|
||||
|
||||
/**
|
||||
* Returns a stream consisting of the remaining elements of this stream
|
||||
* after indexing {@code startInclusive} elements into the stream. If the
|
||||
* {@code startInclusive} index lies past the end of this stream then an
|
||||
* after discarding the first {@code startInclusive} elements of the stream.
|
||||
* If this stream contains fewer than {@code startInclusive} elements then an
|
||||
* empty stream will be returned.
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">stateful
|
||||
@ -269,10 +312,10 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
|
||||
|
||||
/**
|
||||
* Returns a stream consisting of the remaining elements of this stream
|
||||
* after indexing {@code startInclusive} elements into the stream and
|
||||
* truncated to contain no more than {@code endExclusive - startInclusive}
|
||||
* elements. If the {@code startInclusive} index lies past the end
|
||||
* of this stream then an empty stream will be returned.
|
||||
* after discarding the first {@code startInclusive} elements and truncating
|
||||
* the result to be no longer than {@code endExclusive - startInclusive}
|
||||
* elements in length. If this stream contains fewer than
|
||||
* {@code startInclusive} elements then an empty stream will be returned.
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
|
||||
* stateful intermediate operation</a>.
|
||||
@ -421,12 +464,12 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
|
||||
/**
|
||||
* Performs a <a href="package-summary.html#MutableReduction">mutable
|
||||
* reduction</a> operation on the elements of this stream. A mutable
|
||||
* reduction is one in which the reduced value is a mutable value holder,
|
||||
* reduction is one in which the reduced value is a mutable result container,
|
||||
* such as an {@code ArrayList}, and elements are incorporated by updating
|
||||
* the state of the result, rather than by replacing the result. This
|
||||
* the state of the result rather than by replacing the result. This
|
||||
* produces a result equivalent to:
|
||||
* <pre>{@code
|
||||
* R result = resultFactory.get();
|
||||
* R result = supplier.get();
|
||||
* for (double element : this stream)
|
||||
* accumulator.accept(result, element);
|
||||
* return result;
|
||||
@ -440,10 +483,9 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
|
||||
* operation</a>.
|
||||
*
|
||||
* @param <R> type of the result
|
||||
* @param resultFactory a function that creates a new result container.
|
||||
* For a parallel execution, this function may be
|
||||
* called multiple times and must return a fresh value
|
||||
* each time.
|
||||
* @param supplier a function that creates a new result container. For a
|
||||
* parallel execution, this function may be called
|
||||
* multiple times and must return a fresh value each time.
|
||||
* @param accumulator an <a href="package-summary.html#Associativity">associative</a>
|
||||
* <a href="package-summary.html#NonInterference">non-interfering,
|
||||
* stateless</a> function for incorporating an additional
|
||||
@ -455,7 +497,7 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
|
||||
* @return the result of the reduction
|
||||
* @see Stream#collect(Supplier, BiConsumer, BiConsumer)
|
||||
*/
|
||||
<R> R collect(Supplier<R> resultFactory,
|
||||
<R> R collect(Supplier<R> supplier,
|
||||
ObjDoubleConsumer<R> accumulator,
|
||||
BiConsumer<R, R> combiner);
|
||||
|
||||
@ -467,12 +509,15 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
|
||||
* yield more accurate results. If any stream element is a {@code NaN} or
|
||||
* the sum is at any point a {@code NaN} then the sum will be {@code NaN}.
|
||||
* This is a special case of a
|
||||
* <a href="package-summary.html#MutableReduction">reduction</a> and is
|
||||
* <a href="package-summary.html#Reduction">reduction</a> and is
|
||||
* equivalent to:
|
||||
* <pre>{@code
|
||||
* return reduce(0, Double::sum);
|
||||
* }</pre>
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">terminal
|
||||
* operation</a>.
|
||||
*
|
||||
* @return the sum of elements in this stream
|
||||
*/
|
||||
double sum();
|
||||
@ -483,12 +528,15 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
|
||||
* element will be {@code Double.NaN} if any stream element was NaN. Unlike
|
||||
* the numerical comparison operators, this method considers negative zero
|
||||
* to be strictly smaller than positive zero. This is a special case of a
|
||||
* <a href="package-summary.html#MutableReduction">reduction</a> and is
|
||||
* <a href="package-summary.html#Reduction">reduction</a> and is
|
||||
* equivalent to:
|
||||
* <pre>{@code
|
||||
* return reduce(Double::min);
|
||||
* }</pre>
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">terminal
|
||||
* operation</a>.
|
||||
*
|
||||
* @return an {@code OptionalDouble} containing the minimum element of this
|
||||
* stream, or an empty optional if the stream is empty
|
||||
*/
|
||||
@ -501,12 +549,15 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
|
||||
* the numerical comparison operators, this method considers negative zero
|
||||
* to be strictly smaller than positive zero. This is a
|
||||
* special case of a
|
||||
* <a href="package-summary.html#MutableReduction">reduction</a> and is
|
||||
* <a href="package-summary.html#Reduction">reduction</a> and is
|
||||
* equivalent to:
|
||||
* <pre>{@code
|
||||
* return reduce(Double::max);
|
||||
* }</pre>
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">terminal
|
||||
* operation</a>.
|
||||
*
|
||||
* @return an {@code OptionalDouble} containing the maximum element of this
|
||||
* stream, or an empty optional if the stream is empty
|
||||
*/
|
||||
@ -514,7 +565,7 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
|
||||
|
||||
/**
|
||||
* Returns the count of elements in this stream. This is a special case of
|
||||
* a <a href="package-summary.html#MutableReduction">reduction</a> and is
|
||||
* a <a href="package-summary.html#Reduction">reduction</a> and is
|
||||
* equivalent to:
|
||||
* <pre>{@code
|
||||
* return mapToLong(e -> 1L).sum();
|
||||
@ -535,7 +586,10 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
|
||||
* magnitude tend to yield more accurate results. If any recorded value is
|
||||
* a {@code NaN} or the sum is at any point a {@code NaN} then the average
|
||||
* will be {@code NaN}. This is a special case of a
|
||||
* <a href="package-summary.html#MutableReduction">reduction</a>.
|
||||
* <a href="package-summary.html#Reduction">reduction</a>.
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">terminal
|
||||
* operation</a>.
|
||||
*
|
||||
* @return an {@code OptionalDouble} containing the average element of this
|
||||
* stream, or an empty optional if the stream is empty
|
||||
@ -545,7 +599,10 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
|
||||
/**
|
||||
* Returns a {@code DoubleSummaryStatistics} describing various summary data
|
||||
* about the elements of this stream. This is a special
|
||||
* case of a <a href="package-summary.html#MutableReduction">reduction</a>.
|
||||
* case of a <a href="package-summary.html#Reduction">reduction</a>.
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">terminal
|
||||
* operation</a>.
|
||||
*
|
||||
* @return a {@code DoubleSummaryStatistics} describing various summary data
|
||||
* about the elements of this stream
|
||||
@ -602,9 +659,8 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
|
||||
|
||||
/**
|
||||
* Returns an {@link OptionalDouble} describing the first element of this
|
||||
* stream (in the encounter order), or an empty {@code OptionalDouble} if
|
||||
* the stream is empty. If the stream has no encounter order, then any
|
||||
* element may be returned.
|
||||
* stream, or an empty {@code OptionalDouble} if the stream is empty. If
|
||||
* the stream has no encounter order, then any element may be returned.
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
|
||||
* terminal operation</a>.
|
||||
@ -624,8 +680,8 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
|
||||
* <p>The behavior of this operation is explicitly nondeterministic; it is
|
||||
* free to select any element in the stream. This is to allow for maximal
|
||||
* performance in parallel operations; the cost is that multiple invocations
|
||||
* on the same source may not return the same result. (If the first element
|
||||
* in the encounter order is desired, use {@link #findFirst()} instead.)
|
||||
* on the same source may not return the same result. (If a stable result
|
||||
* is desired, use {@link #findFirst()} instead.)
|
||||
*
|
||||
* @return an {@code OptionalDouble} describing some element of this stream,
|
||||
* or an empty {@code OptionalDouble} if the stream is empty
|
||||
@ -637,6 +693,9 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
|
||||
* Returns a {@code Stream} consisting of the elements of this stream,
|
||||
* boxed to {@code Double}.
|
||||
*
|
||||
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
|
||||
* operation</a>.
|
||||
*
|
||||
* @return a {@code Stream} consistent of the elements of this stream,
|
||||
* each boxed to a {@code Double}
|
||||
*/
|
||||
@ -686,7 +745,7 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a sequential stream whose elements are the specified values.
|
||||
* Returns a sequential ordered stream whose elements are the specified values.
|
||||
*
|
||||
* @param values the elements of the new stream
|
||||
* @return the new stream
|
||||
@ -696,7 +755,7 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an infinite sequential {@code DoubleStream} produced by iterative
|
||||
* Returns an infinite sequential ordered {@code DoubleStream} produced by iterative
|
||||
* application of a function {@code f} to an initial element {@code seed},
|
||||
* producing a {@code Stream} consisting of {@code seed}, {@code f(seed)},
|
||||
* {@code f(f(seed))}, etc.
|
||||
@ -734,8 +793,8 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a sequential {@code DoubleStream} where each element is
|
||||
* generated by an {@code DoubleSupplier}. This is suitable for generating
|
||||
* Returns a sequential stream where each element is generated by
|
||||
* the provided {@code DoubleSupplier}. This is suitable for generating
|
||||
* constant streams, streams of random elements, etc.
|
||||
*
|
||||
* @param s the {@code DoubleSupplier} for generated elements
|
||||
@ -748,16 +807,16 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a lazy concatenated {@code DoubleStream} whose elements are all the
|
||||
* elements of a first {@code DoubleStream} succeeded by all the elements of the
|
||||
* second {@code DoubleStream}. The resulting stream is ordered if both
|
||||
* Creates a lazily concatenated stream whose elements are all the
|
||||
* elements of the first stream followed by all the elements of the
|
||||
* second stream. The resulting stream is ordered if both
|
||||
* of the input streams are ordered, and parallel if either of the input
|
||||
* streams is parallel. When the resulting stream is closed, the close
|
||||
* handlers for both input streams are invoked.
|
||||
*
|
||||
* @param a the first stream
|
||||
* @param b the second stream to concatenate on to end of the first stream
|
||||
* @return the concatenation of the two streams
|
||||
* @param b the second stream
|
||||
* @return the concatenation of the two input streams
|
||||
*/
|
||||
public static DoubleStream concat(DoubleStream a, DoubleStream b) {
|
||||
Objects.requireNonNull(a);
|
||||
@ -772,9 +831,9 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
|
||||
/**
|
||||
* A mutable builder for a {@code DoubleStream}.
|
||||
*
|
||||
* <p>A stream builder has a lifecycle, where it starts in a building
|
||||
* phase, during which elements can be added, and then transitions to a
|
||||
* built phase, after which elements may not be added. The built phase
|
||||
* <p>A stream builder has a lifecycle, which starts in a building
|
||||
* phase, during which elements can be added, and then transitions to a built
|
||||
* phase, after which elements may not be added. The built phase
|
||||
* begins when the {@link #build()} method is called, which creates an
|
||||
* ordered stream whose elements are the elements that were added to the
|
||||
* stream builder, in the order they were added.
|
||||
|
||||
@ -349,8 +349,8 @@ abstract class IntPipeline<E_IN>
|
||||
}
|
||||
|
||||
@Override
|
||||
public final IntStream peek(IntConsumer consumer) {
|
||||
Objects.requireNonNull(consumer);
|
||||
public final IntStream peek(IntConsumer action) {
|
||||
Objects.requireNonNull(action);
|
||||
return new StatelessOp<Integer>(this, StreamShape.INT_VALUE,
|
||||
0) {
|
||||
@Override
|
||||
@ -358,7 +358,7 @@ abstract class IntPipeline<E_IN>
|
||||
return new Sink.ChainedInt<Integer>(sink) {
|
||||
@Override
|
||||
public void accept(int t) {
|
||||
consumer.accept(t);
|
||||
action.accept(t);
|
||||
downstream.accept(t);
|
||||
}
|
||||
};
|
||||
@ -473,14 +473,14 @@ abstract class IntPipeline<E_IN>
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <R> R collect(Supplier<R> resultFactory,
|
||||
public final <R> R collect(Supplier<R> supplier,
|
||||
ObjIntConsumer<R> accumulator,
|
||||
BiConsumer<R, R> combiner) {
|
||||
BinaryOperator<R> operator = (left, right) -> {
|
||||
combiner.accept(left, right);
|
||||
return left;
|
||||
};
|
||||
return evaluate(ReduceOps.makeInt(resultFactory, accumulator, operator));
|
||||
return evaluate(ReduceOps.makeInt(supplier, accumulator, operator));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -24,7 +24,11 @@
|
||||
*/
|
||||
package java.util.stream;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.IntSummaryStatistics;
|
||||
import java.util.Objects;
|
||||
import java.util.OptionalDouble;
|
||||
@ -32,6 +36,7 @@ import java.util.OptionalInt;
|
||||
import java.util.PrimitiveIterator;
|
||||
import java.util.Spliterator;
|
||||
import java.util.Spliterators;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.IntBinaryOperator;
|
||||
@ -46,40 +51,87 @@ import java.util.function.ObjIntConsumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* A sequence of primitive integer elements supporting sequential and parallel
|
||||
* bulk operations. Streams support lazy intermediate operations (transforming
|
||||
* a stream to another stream) such as {@code filter} and {@code map}, and terminal
|
||||
* operations (consuming the contents of a stream to produce a result or
|
||||
* side-effect), such as {@code forEach}, {@code findFirst}, and {@code
|
||||
* iterator}. Once an operation has been performed on a stream, it
|
||||
* is considered <em>consumed</em> and no longer usable for other operations.
|
||||
* A sequence of elements supporting sequential and parallel aggregate
|
||||
* operations. The following example illustrates an aggregate operation using
|
||||
* {@link Stream} and {@link IntStream}:
|
||||
*
|
||||
* <p>For sequential stream pipelines, all operations are performed in the
|
||||
* <a href="package-summary.html#Ordering">encounter order</a> of the pipeline
|
||||
* source, if the pipeline source has a defined encounter order.
|
||||
* <pre>{@code
|
||||
* int sum = widgets.stream()
|
||||
* .filter(w -> w.getColor() == RED)
|
||||
* .mapToInt(w -> w.getWeight())
|
||||
* .sum();
|
||||
* }</pre>
|
||||
*
|
||||
* <p>For parallel stream pipelines, unless otherwise specified, intermediate
|
||||
* stream operations preserve the <a href="package-summary.html#Ordering">
|
||||
* encounter order</a> of their source, and terminal operations
|
||||
* respect the encounter order of their source, if the source
|
||||
* has an encounter order. Provided that and parameters to stream operations
|
||||
* satisfy the <a href="package-summary.html#NonInterference">non-interference
|
||||
* requirements</a>, and excepting differences arising from the absence of
|
||||
* a defined encounter order, the result of a stream pipeline should be the
|
||||
* stable across multiple executions of the same operations on the same source.
|
||||
* However, the timing and thread in which side-effects occur (for those
|
||||
* operations which are allowed to produce side-effects, such as
|
||||
* {@link #forEach(IntConsumer)}), are explicitly nondeterministic for parallel
|
||||
* execution of stream pipelines.
|
||||
* In this example, {@code widgets} is a {@code Collection<Widget>}. We create
|
||||
* a stream of {@code Widget} objects via {@link Collection#stream Collection.stream()},
|
||||
* filter it to produce a stream containing only the red widgets, and then
|
||||
* transform it into a stream of {@code int} values representing the weight of
|
||||
* each red widget. Then this stream is summed to produce a total weight.
|
||||
*
|
||||
* <p>Unless otherwise noted, passing a {@code null} argument to any stream
|
||||
* method may result in a {@link NullPointerException}.
|
||||
* <p>To perform a computation, stream
|
||||
* <a href="package-summary.html#StreamOps">operations</a> are composed into a
|
||||
* <em>stream pipeline</em>. A stream pipeline consists of a source (which
|
||||
* might be an array, a collection, a generator function, an IO channel,
|
||||
* etc), zero or more <em>intermediate operations</em> (which transform a
|
||||
* stream into another stream, such as {@link IntStream#filter(IntPredicate)}), and a
|
||||
* <em>terminal operation</em> (which produces a result or side-effect, such
|
||||
* as {@link IntStream#sum()} or {@link IntStream#forEach(IntConsumer)}).
|
||||
* Streams are lazy; computation on the source data is only performed when the
|
||||
* terminal operation is initiated, and source elements are consumed only
|
||||
* as needed.
|
||||
*
|
||||
* @apiNote
|
||||
* Streams are not data structures; they do not manage the storage for their
|
||||
* elements, nor do they support access to individual elements. However,
|
||||
* you can use the {@link #iterator()} or {@link #spliterator()} operations to
|
||||
* perform a controlled traversal.
|
||||
* <p>Collections and streams, while bearing some superficial similarities,
|
||||
* have different goals. Collections are primarily concerned with the efficient
|
||||
* management of, and access to, their elements. By contrast, streams do not
|
||||
* provide a means to directly access or manipulate their elements, and are
|
||||
* instead concerned with declaratively describing their source and the
|
||||
* computational operations which will be performed in aggregate on that source.
|
||||
* However, if the provided stream operations do not offer the desired
|
||||
* functionality, the {@link #iterator()} and {@link #spliterator()} operations
|
||||
* can be used to perform a controlled traversal.
|
||||
*
|
||||
* <p>A stream pipeline, like the "widgets" example above, can be viewed as
|
||||
* a <em>query</em> on the stream source. Unless the source was explicitly
|
||||
* designed for concurrent modification (such as a {@link ConcurrentHashMap}),
|
||||
* unpredictable or erroneous behavior may result from modifying the stream
|
||||
* source while it is being queried.
|
||||
*
|
||||
* <p>Most stream operations accept parameters that describe user-specified
|
||||
* behavior, such as the lambda expression {@code w -> w.getWeight()} passed to
|
||||
* {@code mapToInt} in the example above. Such parameters are always instances
|
||||
* of a <a href="../function/package-summary.html">functional interface</a> such
|
||||
* as {@link java.util.function.Function}, and are often lambda expressions or
|
||||
* method references. These parameters can never be null, should not modify the
|
||||
* stream source, and should be
|
||||
* <a href="package-summary.html#NonInterference">effectively stateless</a>
|
||||
* (their result should not depend on any state that might change during
|
||||
* execution of the stream pipeline.)
|
||||
*
|
||||
* <p>A stream should be operated on (invoking an intermediate or terminal stream
|
||||
* operation) only once. This rules out, for example, "forked" streams, where
|
||||
* the same source feeds two or more pipelines, or multiple traversals of the
|
||||
* same stream. A stream implementation may throw {@link IllegalStateException}
|
||||
* if it detects that the stream is being reused. However, since some stream
|
||||
* operations may return their receiver rather than a new stream object, it may
|
||||
* not be possible to detect reuse in all cases.
|
||||
*
|
||||
* <p>Streams have a {@link #close()} method and implement {@link AutoCloseable},
|
||||
* but nearly all stream instances do not actually need to be closed after use.
|
||||
* Generally, only streams whose source is an IO channel (such as those returned
|
||||
* by {@link Files#lines(Path, Charset)}) will require closing. Most streams
|
||||
* are backed by collections, arrays, or generating functions, which require no
|
||||
* special resource management. (If a stream does require closing, it can be
|
||||
* declared as a resource in a {@code try}-with-resources statement.)
|
||||
*
|
||||
* <p>Stream pipelines may execute either sequentially or in
|
||||
* <a href="package-summary.html#Parallelism">parallel</a>. This
|
||||
* execution mode is a property of the stream. Streams are created
|
||||
* with an initial choice of sequential or parallel execution. (For example,
|
||||
* {@link Collection#stream() Collection.stream()} creates a sequential stream,
|
||||
* and {@link Collection#parallelStream() Collection.parallelStream()} creates
|
||||
* a parallel one.) This choice of execution mode may be modified by the
|
||||
* {@link #sequential()} or {@link #parallel()} methods, and may be queried with
|
||||
* the {@link #isParallel()} method.
|
||||
*
|
||||
* @since 1.8
|
||||
* @see <a href="package-summary.html">java.util.stream</a>
|
||||
@ -160,22 +212,13 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
|
||||
/**
|
||||
* Returns a stream consisting of the results of replacing each element of
|
||||
* this stream with the contents of the stream produced by applying the
|
||||
* provided mapping function to each element.
|
||||
* provided mapping function to each element. (If the result of the mapping
|
||||
* function is {@code null}, this is treated as if the result was an empty
|
||||
* stream.)
|
||||
*
|
||||
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
|
||||
* operation</a>.
|
||||
*
|
||||
* @apiNote
|
||||
* The {@code flatMap()} operation has the effect of applying a one-to-many
|
||||
* tranformation to the elements of the stream, and then flattening the
|
||||
* resulting elements into a new stream. For example, if {@code orders}
|
||||
* is a stream of purchase orders, and each purchase order contains a
|
||||
* collection of line items, then the following produces a stream of line
|
||||
* items:
|
||||
* <pre>{@code
|
||||
* orderStream.flatMap(order -> order.getLineItems().stream())...
|
||||
* }</pre>
|
||||
*
|
||||
* @param mapper a <a href="package-summary.html#NonInterference">
|
||||
* non-interfering, stateless</a> function to apply to
|
||||
* each element which produces an {@code IntStream} of new
|
||||
@ -224,18 +267,18 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
|
||||
* <pre>{@code
|
||||
* list.stream()
|
||||
* .filter(filteringFunction)
|
||||
* .peek(e -> {System.out.println("Filtered value: " + e); });
|
||||
* .peek(e -> System.out.println("Filtered value: " + e));
|
||||
* .map(mappingFunction)
|
||||
* .peek(e -> {System.out.println("Mapped value: " + e); });
|
||||
* .peek(e -> System.out.println("Mapped value: " + e));
|
||||
* .collect(Collectors.toIntSummaryStastistics());
|
||||
* }</pre>
|
||||
*
|
||||
* @param consumer a <a href="package-summary.html#NonInterference">
|
||||
* non-interfering</a> action to perform on the elements as
|
||||
* they are consumed from the stream
|
||||
* @param action a <a href="package-summary.html#NonInterference">
|
||||
* non-interfering</a> action to perform on the elements as
|
||||
* they are consumed from the stream
|
||||
* @return the new stream
|
||||
*/
|
||||
IntStream peek(IntConsumer consumer);
|
||||
IntStream peek(IntConsumer action);
|
||||
|
||||
/**
|
||||
* Returns a stream consisting of the elements of this stream, truncated
|
||||
@ -252,8 +295,8 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
|
||||
|
||||
/**
|
||||
* Returns a stream consisting of the remaining elements of this stream
|
||||
* after indexing {@code startInclusive} elements into the stream. If the
|
||||
* {@code startInclusive} index lies past the end of this stream then an
|
||||
* after discarding the first {@code startInclusive} elements of the stream.
|
||||
* If this stream contains fewer than {@code startInclusive} elements then an
|
||||
* empty stream will be returned.
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">stateful
|
||||
@ -267,10 +310,10 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
|
||||
|
||||
/**
|
||||
* Returns a stream consisting of the remaining elements of this stream
|
||||
* after indexing {@code startInclusive} elements into the stream and
|
||||
* truncated to contain no more than {@code endExclusive - startInclusive}
|
||||
* elements. If the {@code startInclusive} index lies past the end
|
||||
* of this stream then an empty stream will be returned.
|
||||
* after discarding the first {@code startInclusive} elements and truncating
|
||||
* the result to be no longer than {@code endExclusive - startInclusive}
|
||||
* elements in length. If this stream contains fewer than
|
||||
* {@code startInclusive} elements then an empty stream will be returned.
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
|
||||
* stateful intermediate operation</a>.
|
||||
@ -419,12 +462,12 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
|
||||
/**
|
||||
* Performs a <a href="package-summary.html#MutableReduction">mutable
|
||||
* reduction</a> operation on the elements of this stream. A mutable
|
||||
* reduction is one in which the reduced value is a mutable value holder,
|
||||
* reduction is one in which the reduced value is a mutable result container,
|
||||
* such as an {@code ArrayList}, and elements are incorporated by updating
|
||||
* the state of the result, rather than by replacing the result. This
|
||||
* the state of the result rather than by replacing the result. This
|
||||
* produces a result equivalent to:
|
||||
* <pre>{@code
|
||||
* R result = resultFactory.get();
|
||||
* R result = supplier.get();
|
||||
* for (int element : this stream)
|
||||
* accumulator.accept(result, element);
|
||||
* return result;
|
||||
@ -437,10 +480,9 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
|
||||
* operation</a>.
|
||||
*
|
||||
* @param <R> type of the result
|
||||
* @param resultFactory a function that creates a new result container.
|
||||
* For a parallel execution, this function may be
|
||||
* called multiple times and must return a fresh value
|
||||
* each time.
|
||||
* @param supplier a function that creates a new result container. For a
|
||||
* parallel execution, this function may be called
|
||||
* multiple times and must return a fresh value each time.
|
||||
* @param accumulator an <a href="package-summary.html#Associativity">associative</a>
|
||||
* <a href="package-summary.html#NonInterference">non-interfering,
|
||||
* stateless</a> function for incorporating an additional
|
||||
@ -452,18 +494,21 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
|
||||
* @return the result of the reduction
|
||||
* @see Stream#collect(Supplier, BiConsumer, BiConsumer)
|
||||
*/
|
||||
<R> R collect(Supplier<R> resultFactory,
|
||||
<R> R collect(Supplier<R> supplier,
|
||||
ObjIntConsumer<R> accumulator,
|
||||
BiConsumer<R, R> combiner);
|
||||
|
||||
/**
|
||||
* Returns the sum of elements in this stream. This is a special case
|
||||
* of a <a href="package-summary.html#MutableReduction">reduction</a>
|
||||
* of a <a href="package-summary.html#Reduction">reduction</a>
|
||||
* and is equivalent to:
|
||||
* <pre>{@code
|
||||
* return reduce(0, Integer::sum);
|
||||
* }</pre>
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">terminal
|
||||
* operation</a>.
|
||||
*
|
||||
* @return the sum of elements in this stream
|
||||
*/
|
||||
int sum();
|
||||
@ -471,7 +516,7 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
|
||||
/**
|
||||
* Returns an {@code OptionalInt} describing the minimum element of this
|
||||
* stream, or an empty optional if this stream is empty. This is a special
|
||||
* case of a <a href="package-summary.html#MutableReduction">reduction</a>
|
||||
* case of a <a href="package-summary.html#Reduction">reduction</a>
|
||||
* and is equivalent to:
|
||||
* <pre>{@code
|
||||
* return reduce(Integer::min);
|
||||
@ -479,7 +524,6 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">terminal operation</a>.
|
||||
*
|
||||
|
||||
* @return an {@code OptionalInt} containing the minimum element of this
|
||||
* stream, or an empty {@code OptionalInt} if the stream is empty
|
||||
*/
|
||||
@ -488,7 +532,7 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
|
||||
/**
|
||||
* Returns an {@code OptionalInt} describing the maximum element of this
|
||||
* stream, or an empty optional if this stream is empty. This is a special
|
||||
* case of a <a href="package-summary.html#MutableReduction">reduction</a>
|
||||
* case of a <a href="package-summary.html#Reduction">reduction</a>
|
||||
* and is equivalent to:
|
||||
* <pre>{@code
|
||||
* return reduce(Integer::max);
|
||||
@ -504,7 +548,7 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
|
||||
|
||||
/**
|
||||
* Returns the count of elements in this stream. This is a special case of
|
||||
* a <a href="package-summary.html#MutableReduction">reduction</a> and is
|
||||
* a <a href="package-summary.html#Reduction">reduction</a> and is
|
||||
* equivalent to:
|
||||
* <pre>{@code
|
||||
* return mapToLong(e -> 1L).sum();
|
||||
@ -520,7 +564,10 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
|
||||
* Returns an {@code OptionalDouble} describing the arithmetic mean of elements of
|
||||
* this stream, or an empty optional if this stream is empty. This is a
|
||||
* special case of a
|
||||
* <a href="package-summary.html#MutableReduction">reduction</a>.
|
||||
* <a href="package-summary.html#Reduction">reduction</a>.
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">terminal
|
||||
* operation</a>.
|
||||
*
|
||||
* @return an {@code OptionalDouble} containing the average element of this
|
||||
* stream, or an empty optional if the stream is empty
|
||||
@ -530,7 +577,10 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
|
||||
/**
|
||||
* Returns an {@code IntSummaryStatistics} describing various
|
||||
* summary data about the elements of this stream. This is a special
|
||||
* case of a <a href="package-summary.html#MutableReduction">reduction</a>.
|
||||
* case of a <a href="package-summary.html#Reduction">reduction</a>.
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">terminal
|
||||
* operation</a>.
|
||||
*
|
||||
* @return an {@code IntSummaryStatistics} describing various summary data
|
||||
* about the elements of this stream
|
||||
@ -587,9 +637,8 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
|
||||
|
||||
/**
|
||||
* Returns an {@link OptionalInt} describing the first element of this
|
||||
* stream (in the encounter order), or an empty {@code OptionalInt} if the
|
||||
* stream is empty. If the stream has no encounter order, then any element
|
||||
* may be returned.
|
||||
* stream, or an empty {@code OptionalInt} if the stream is empty. If the
|
||||
* stream has no encounter order, then any element may be returned.
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
|
||||
* terminal operation</a>.
|
||||
@ -609,8 +658,8 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
|
||||
* <p>The behavior of this operation is explicitly nondeterministic; it is
|
||||
* free to select any element in the stream. This is to allow for maximal
|
||||
* performance in parallel operations; the cost is that multiple invocations
|
||||
* on the same source may not return the same result. (If the first element
|
||||
* in the encounter order is desired, use {@link #findFirst()} instead.)
|
||||
* on the same source may not return the same result. (If a stable result
|
||||
* is desired, use {@link #findFirst()} instead.)
|
||||
*
|
||||
* @return an {@code OptionalInt} describing some element of this stream, or
|
||||
* an empty {@code OptionalInt} if the stream is empty
|
||||
@ -622,6 +671,9 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
|
||||
* Returns a {@code LongStream} consisting of the elements of this stream,
|
||||
* converted to {@code long}.
|
||||
*
|
||||
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
|
||||
* operation</a>.
|
||||
*
|
||||
* @return a {@code LongStream} consisting of the elements of this stream,
|
||||
* converted to {@code long}
|
||||
*/
|
||||
@ -631,6 +683,9 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
|
||||
* Returns a {@code DoubleStream} consisting of the elements of this stream,
|
||||
* converted to {@code double}.
|
||||
*
|
||||
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
|
||||
* operation</a>.
|
||||
*
|
||||
* @return a {@code DoubleStream} consisting of the elements of this stream,
|
||||
* converted to {@code double}
|
||||
*/
|
||||
@ -640,6 +695,9 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
|
||||
* Returns a {@code Stream} consisting of the elements of this stream,
|
||||
* each boxed to an {@code Integer}.
|
||||
*
|
||||
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
|
||||
* operation</a>.
|
||||
*
|
||||
* @return a {@code Stream} consistent of the elements of this stream,
|
||||
* each boxed to an {@code Integer}
|
||||
*/
|
||||
@ -688,7 +746,7 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a sequential stream whose elements are the specified values.
|
||||
* Returns a sequential ordered stream whose elements are the specified values.
|
||||
*
|
||||
* @param values the elements of the new stream
|
||||
* @return the new stream
|
||||
@ -698,7 +756,7 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an infinite sequential {@code IntStream} produced by iterative
|
||||
* Returns an infinite sequential ordered {@code IntStream} produced by iterative
|
||||
* application of a function {@code f} to an initial element {@code seed},
|
||||
* producing a {@code Stream} consisting of {@code seed}, {@code f(seed)},
|
||||
* {@code f(f(seed))}, etc.
|
||||
@ -736,8 +794,8 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a sequential {@code IntStream} where each element is
|
||||
* generated by an {@code IntSupplier}. This is suitable for generating
|
||||
* Returns a sequential stream where each element is generated by
|
||||
* the provided {@code IntSupplier}. This is suitable for generating
|
||||
* constant streams, streams of random elements, etc.
|
||||
*
|
||||
* @param s the {@code IntSupplier} for generated elements
|
||||
@ -750,7 +808,7 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a sequential {@code IntStream} from {@code startInclusive}
|
||||
* Returns a sequential ordered {@code IntStream} from {@code startInclusive}
|
||||
* (inclusive) to {@code endExclusive} (exclusive) by an incremental step of
|
||||
* {@code 1}.
|
||||
*
|
||||
@ -776,7 +834,7 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a sequential {@code IntStream} from {@code startInclusive}
|
||||
* Returns a sequential ordered {@code IntStream} from {@code startInclusive}
|
||||
* (inclusive) to {@code endInclusive} (inclusive) by an incremental step of
|
||||
* {@code 1}.
|
||||
*
|
||||
@ -802,16 +860,16 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a lazy concatenated {@code IntStream} whose elements are all the
|
||||
* elements of a first {@code IntStream} succeeded by all the elements of the
|
||||
* second {@code IntStream}. The resulting stream is ordered if both
|
||||
* Creates a lazily concatenated stream whose elements are all the
|
||||
* elements of the first stream followed by all the elements of the
|
||||
* second stream. The resulting stream is ordered if both
|
||||
* of the input streams are ordered, and parallel if either of the input
|
||||
* streams is parallel. When the resulting stream is closed, the close
|
||||
* handlers for both input streams are invoked.
|
||||
*
|
||||
* @param a the first stream
|
||||
* @param b the second stream to concatenate on to end of the first stream
|
||||
* @return the concatenation of the two streams
|
||||
* @param b the second stream
|
||||
* @return the concatenation of the two input streams
|
||||
*/
|
||||
public static IntStream concat(IntStream a, IntStream b) {
|
||||
Objects.requireNonNull(a);
|
||||
@ -826,9 +884,9 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
|
||||
/**
|
||||
* A mutable builder for an {@code IntStream}.
|
||||
*
|
||||
* <p>A stream builder has a lifecycle, where it starts in a building
|
||||
* phase, during which elements can be added, and then transitions to a
|
||||
* built phase, after which elements may not be added. The built phase
|
||||
* <p>A stream builder has a lifecycle, which starts in a building
|
||||
* phase, during which elements can be added, and then transitions to a built
|
||||
* phase, after which elements may not be added. The built phase
|
||||
* begins when the {@link #build()} method is called, which creates an
|
||||
* ordered stream whose elements are the elements that were added to the
|
||||
* stream builder, in the order they were added.
|
||||
|
||||
@ -330,8 +330,8 @@ abstract class LongPipeline<E_IN>
|
||||
}
|
||||
|
||||
@Override
|
||||
public final LongStream peek(LongConsumer consumer) {
|
||||
Objects.requireNonNull(consumer);
|
||||
public final LongStream peek(LongConsumer action) {
|
||||
Objects.requireNonNull(action);
|
||||
return new StatelessOp<Long>(this, StreamShape.LONG_VALUE,
|
||||
0) {
|
||||
@Override
|
||||
@ -339,7 +339,7 @@ abstract class LongPipeline<E_IN>
|
||||
return new Sink.ChainedLong<Long>(sink) {
|
||||
@Override
|
||||
public void accept(long t) {
|
||||
consumer.accept(t);
|
||||
action.accept(t);
|
||||
downstream.accept(t);
|
||||
}
|
||||
};
|
||||
@ -455,14 +455,14 @@ abstract class LongPipeline<E_IN>
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <R> R collect(Supplier<R> resultFactory,
|
||||
public final <R> R collect(Supplier<R> supplier,
|
||||
ObjLongConsumer<R> accumulator,
|
||||
BiConsumer<R, R> combiner) {
|
||||
BinaryOperator<R> operator = (left, right) -> {
|
||||
combiner.accept(left, right);
|
||||
return left;
|
||||
};
|
||||
return evaluate(ReduceOps.makeLong(resultFactory, accumulator, operator));
|
||||
return evaluate(ReduceOps.makeLong(supplier, accumulator, operator));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -24,7 +24,11 @@
|
||||
*/
|
||||
package java.util.stream;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.LongSummaryStatistics;
|
||||
import java.util.Objects;
|
||||
import java.util.OptionalDouble;
|
||||
@ -32,6 +36,7 @@ import java.util.OptionalLong;
|
||||
import java.util.PrimitiveIterator;
|
||||
import java.util.Spliterator;
|
||||
import java.util.Spliterators;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.LongBinaryOperator;
|
||||
@ -46,40 +51,87 @@ import java.util.function.ObjLongConsumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* A sequence of primitive long elements supporting sequential and parallel
|
||||
* bulk operations. Streams support lazy intermediate operations (transforming
|
||||
* a stream to another stream) such as {@code filter} and {@code map}, and terminal
|
||||
* operations (consuming the contents of a stream to produce a result or
|
||||
* side-effect), such as {@code forEach}, {@code findFirst}, and {@code
|
||||
* iterator}. Once an operation has been performed on a stream, it
|
||||
* is considered <em>consumed</em> and no longer usable for other operations.
|
||||
* A sequence of elements supporting sequential and parallel aggregate
|
||||
* operations. The following example illustrates an aggregate operation using
|
||||
* {@link Stream} and {@link LongStream}:
|
||||
*
|
||||
* <p>For sequential stream pipelines, all operations are performed in the
|
||||
* <a href="package-summary.html#Ordering">encounter order</a> of the pipeline
|
||||
* source, if the pipeline source has a defined encounter order.
|
||||
* <pre>{@code
|
||||
* long sum = widgets.stream()
|
||||
* .filter(w -> w.getColor() == RED)
|
||||
* .mapToLong(w -> w.getWeight())
|
||||
* .sum();
|
||||
* }</pre>
|
||||
*
|
||||
* <p>For parallel stream pipelines, unless otherwise specified, intermediate
|
||||
* stream operations preserve the <a href="package-summary.html#Ordering">
|
||||
* encounter order</a> of their source, and terminal operations
|
||||
* respect the encounter order of their source, if the source
|
||||
* has an encounter order. Provided that and parameters to stream operations
|
||||
* satisfy the <a href="package-summary.html#NonInterference">non-interference
|
||||
* requirements</a>, and excepting differences arising from the absence of
|
||||
* a defined encounter order, the result of a stream pipeline should be the
|
||||
* stable across multiple executions of the same operations on the same source.
|
||||
* However, the timing and thread in which side-effects occur (for those
|
||||
* operations which are allowed to produce side-effects, such as
|
||||
* {@link #forEach(LongConsumer)}), are explicitly nondeterministic for parallel
|
||||
* execution of stream pipelines.
|
||||
* In this example, {@code widgets} is a {@code Collection<Widget>}. We create
|
||||
* a stream of {@code Widget} objects via {@link Collection#stream Collection.stream()},
|
||||
* filter it to produce a stream containing only the red widgets, and then
|
||||
* transform it into a stream of {@code long} values representing the weight of
|
||||
* each red widget. Then this stream is summed to produce a total weight.
|
||||
*
|
||||
* <p>Unless otherwise noted, passing a {@code null} argument to any stream
|
||||
* method may result in a {@link NullPointerException}.
|
||||
* <p>To perform a computation, stream
|
||||
* <a href="package-summary.html#StreamOps">operations</a> are composed into a
|
||||
* <em>stream pipeline</em>. A stream pipeline consists of a source (which
|
||||
* might be an array, a collection, a generator function, an IO channel,
|
||||
* etc), zero or more <em>intermediate operations</em> (which transform a
|
||||
* stream into another stream, such as {@link LongStream#filter(LongPredicate)}), and a
|
||||
* <em>terminal operation</em> (which produces a result or side-effect, such
|
||||
* as {@link LongStream#sum()} or {@link LongStream#forEach(LongConsumer)}).
|
||||
* Streams are lazy; computation on the source data is only performed when the
|
||||
* terminal operation is initiated, and source elements are consumed only
|
||||
* as needed.
|
||||
*
|
||||
* @apiNote
|
||||
* Streams are not data structures; they do not manage the storage for their
|
||||
* elements, nor do they support access to individual elements. However,
|
||||
* you can use the {@link #iterator()} or {@link #spliterator()} operations to
|
||||
* perform a controlled traversal.
|
||||
* <p>Collections and streams, while bearing some superficial similarities,
|
||||
* have different goals. Collections are primarily concerned with the efficient
|
||||
* management of, and access to, their elements. By contrast, streams do not
|
||||
* provide a means to directly access or manipulate their elements, and are
|
||||
* instead concerned with declaratively describing their source and the
|
||||
* computational operations which will be performed in aggregate on that source.
|
||||
* However, if the provided stream operations do not offer the desired
|
||||
* functionality, the {@link #iterator()} and {@link #spliterator()} operations
|
||||
* can be used to perform a controlled traversal.
|
||||
*
|
||||
* <p>A stream pipeline, like the "widgets" example above, can be viewed as
|
||||
* a <em>query</em> on the stream source. Unless the source was explicitly
|
||||
* designed for concurrent modification (such as a {@link ConcurrentHashMap}),
|
||||
* unpredictable or erroneous behavior may result from modifying the stream
|
||||
* source while it is being queried.
|
||||
*
|
||||
* <p>Most stream operations accept parameters that describe user-specified
|
||||
* behavior, such as the lambda expression {@code w -> w.getWeight()} passed to
|
||||
* {@code mapToLong} in the example above. Such parameters are always instances
|
||||
* of a <a href="../function/package-summary.html">functional interface</a> such
|
||||
* as {@link java.util.function.Function}, and are often lambda expressions or
|
||||
* method references. These parameters can never be null, should not modify the
|
||||
* stream source, and should be
|
||||
* <a href="package-summary.html#NonInterference">effectively stateless</a>
|
||||
* (their result should not depend on any state that might change during
|
||||
* execution of the stream pipeline.)
|
||||
*
|
||||
* <p>A stream should be operated on (invoking an intermediate or terminal stream
|
||||
* operation) only once. This rules out, for example, "forked" streams, where
|
||||
* the same source feeds two or more pipelines, or multiple traversals of the
|
||||
* same stream. A stream implementation may throw {@link IllegalStateException}
|
||||
* if it detects that the stream is being reused. However, since some stream
|
||||
* operations may return their receiver rather than a new stream object, it may
|
||||
* not be possible to detect reuse in all cases.
|
||||
*
|
||||
* <p>Streams have a {@link #close()} method and implement {@link AutoCloseable},
|
||||
* but nearly all stream instances do not actually need to be closed after use.
|
||||
* Generally, only streams whose source is an IO channel (such as those returned
|
||||
* by {@link Files#lines(Path, Charset)}) will require closing. Most streams
|
||||
* are backed by collections, arrays, or generating functions, which require no
|
||||
* special resource management. (If a stream does require closing, it can be
|
||||
* declared as a resource in a {@code try}-with-resources statement.)
|
||||
*
|
||||
* <p>Stream pipelines may execute either sequentially or in
|
||||
* <a href="package-summary.html#Parallelism">parallel</a>. This
|
||||
* execution mode is a property of the stream. Streams are created
|
||||
* with an initial choice of sequential or parallel execution. (For example,
|
||||
* {@link Collection#stream() Collection.stream()} creates a sequential stream,
|
||||
* and {@link Collection#parallelStream() Collection.parallelStream()} creates
|
||||
* a parallel one.) This choice of execution mode may be modified by the
|
||||
* {@link #sequential()} or {@link #parallel()} methods, and may be queried with
|
||||
* the {@link #isParallel()} method.
|
||||
*
|
||||
* @since 1.8
|
||||
* @see <a href="package-summary.html">java.util.stream</a>
|
||||
@ -160,22 +212,13 @@ public interface LongStream extends BaseStream<Long, LongStream> {
|
||||
/**
|
||||
* Returns a stream consisting of the results of replacing each element of
|
||||
* this stream with the contents of the stream produced by applying the
|
||||
* provided mapping function to each element.
|
||||
* provided mapping function to each element. (If the result of the mapping
|
||||
* function is {@code null}, this is treated as if the result was an empty
|
||||
* stream.)
|
||||
*
|
||||
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
|
||||
* operation</a>.
|
||||
*
|
||||
* @apiNote
|
||||
* The {@code flatMap()} operation has the effect of applying a one-to-many
|
||||
* tranformation to the elements of the stream, and then flattening the
|
||||
* resulting elements into a new stream. For example, if {@code orders}
|
||||
* is a stream of purchase orders, and each purchase order contains a
|
||||
* collection of line items, then the following produces a stream of line
|
||||
* items:
|
||||
* <pre>{@code
|
||||
* orderStream.flatMap(order -> order.getLineItems().stream())...
|
||||
* }</pre>
|
||||
*
|
||||
* @param mapper a <a href="package-summary.html#NonInterference">
|
||||
* non-interfering, stateless</a> function to apply to
|
||||
* each element which produces an {@code LongStream} of new
|
||||
@ -224,18 +267,18 @@ public interface LongStream extends BaseStream<Long, LongStream> {
|
||||
* <pre>{@code
|
||||
* list.stream()
|
||||
* .filter(filteringFunction)
|
||||
* .peek(e -> {System.out.println("Filtered value: " + e); });
|
||||
* .peek(e -> System.out.println("Filtered value: " + e));
|
||||
* .map(mappingFunction)
|
||||
* .peek(e -> {System.out.println("Mapped value: " + e); });
|
||||
* .peek(e -> System.out.println("Mapped value: " + e));
|
||||
* .collect(Collectors.toLongSummaryStastistics());
|
||||
* }</pre>
|
||||
*
|
||||
* @param consumer a <a href="package-summary.html#NonInterference">
|
||||
* non-interfering</a> action to perform on the elements as
|
||||
* they are consumed from the stream
|
||||
* @param action a <a href="package-summary.html#NonInterference">
|
||||
* non-interfering</a> action to perform on the elements as
|
||||
* they are consumed from the stream
|
||||
* @return the new stream
|
||||
*/
|
||||
LongStream peek(LongConsumer consumer);
|
||||
LongStream peek(LongConsumer action);
|
||||
|
||||
/**
|
||||
* Returns a stream consisting of the elements of this stream, truncated
|
||||
@ -252,8 +295,8 @@ public interface LongStream extends BaseStream<Long, LongStream> {
|
||||
|
||||
/**
|
||||
* Returns a stream consisting of the remaining elements of this stream
|
||||
* after indexing {@code startInclusive} elements into the stream. If the
|
||||
* {@code startInclusive} index lies past the end of this stream then an
|
||||
* after discarding the first {@code startInclusive} elements of the stream.
|
||||
* If this stream contains fewer than {@code startInclusive} elements then an
|
||||
* empty stream will be returned.
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">stateful
|
||||
@ -267,10 +310,10 @@ public interface LongStream extends BaseStream<Long, LongStream> {
|
||||
|
||||
/**
|
||||
* Returns a stream consisting of the remaining elements of this stream
|
||||
* after indexing {@code startInclusive} elements into the stream and
|
||||
* truncated to contain no more than {@code endExclusive - startInclusive}
|
||||
* elements. If the {@code startInclusive} index lies past the end
|
||||
* of this stream then an empty stream will be returned.
|
||||
* after discarding the first {@code startInclusive} elements and truncating
|
||||
* the result to be no longer than {@code endExclusive - startInclusive}
|
||||
* elements in length. If this stream contains fewer than
|
||||
* {@code startInclusive} elements then an empty stream will be returned.
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
|
||||
* stateful intermediate operation</a>.
|
||||
@ -419,12 +462,12 @@ public interface LongStream extends BaseStream<Long, LongStream> {
|
||||
/**
|
||||
* Performs a <a href="package-summary.html#MutableReduction">mutable
|
||||
* reduction</a> operation on the elements of this stream. A mutable
|
||||
* reduction is one in which the reduced value is a mutable value holder,
|
||||
* reduction is one in which the reduced value is a mutable result container,
|
||||
* such as an {@code ArrayList}, and elements are incorporated by updating
|
||||
* the state of the result, rather than by replacing the result. This
|
||||
* the state of the result rather than by replacing the result. This
|
||||
* produces a result equivalent to:
|
||||
* <pre>{@code
|
||||
* R result = resultFactory.get();
|
||||
* R result = supplier.get();
|
||||
* for (long element : this stream)
|
||||
* accumulator.accept(result, element);
|
||||
* return result;
|
||||
@ -437,10 +480,9 @@ public interface LongStream extends BaseStream<Long, LongStream> {
|
||||
* operation</a>.
|
||||
*
|
||||
* @param <R> type of the result
|
||||
* @param resultFactory a function that creates a new result container.
|
||||
* For a parallel execution, this function may be
|
||||
* called multiple times and must return a fresh value
|
||||
* each time.
|
||||
* @param supplier a function that creates a new result container. For a
|
||||
* parallel execution, this function may be called
|
||||
* multiple times and must return a fresh value each time.
|
||||
* @param accumulator an <a href="package-summary.html#Associativity">associative</a>
|
||||
* <a href="package-summary.html#NonInterference">non-interfering,
|
||||
* stateless</a> function for incorporating an additional
|
||||
@ -452,18 +494,21 @@ public interface LongStream extends BaseStream<Long, LongStream> {
|
||||
* @return the result of the reduction
|
||||
* @see Stream#collect(Supplier, BiConsumer, BiConsumer)
|
||||
*/
|
||||
<R> R collect(Supplier<R> resultFactory,
|
||||
<R> R collect(Supplier<R> supplier,
|
||||
ObjLongConsumer<R> accumulator,
|
||||
BiConsumer<R, R> combiner);
|
||||
|
||||
/**
|
||||
* Returns the sum of elements in this stream. This is a special case
|
||||
* of a <a href="package-summary.html#MutableReduction">reduction</a>
|
||||
* of a <a href="package-summary.html#Reduction">reduction</a>
|
||||
* and is equivalent to:
|
||||
* <pre>{@code
|
||||
* return reduce(0, Long::sum);
|
||||
* }</pre>
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">terminal
|
||||
* operation</a>.
|
||||
*
|
||||
* @return the sum of elements in this stream
|
||||
*/
|
||||
long sum();
|
||||
@ -471,7 +516,7 @@ public interface LongStream extends BaseStream<Long, LongStream> {
|
||||
/**
|
||||
* Returns an {@code OptionalLong} describing the minimum element of this
|
||||
* stream, or an empty optional if this stream is empty. This is a special
|
||||
* case of a <a href="package-summary.html#MutableReduction">reduction</a>
|
||||
* case of a <a href="package-summary.html#Reduction">reduction</a>
|
||||
* and is equivalent to:
|
||||
* <pre>{@code
|
||||
* return reduce(Long::min);
|
||||
@ -479,7 +524,6 @@ public interface LongStream extends BaseStream<Long, LongStream> {
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">terminal operation</a>.
|
||||
*
|
||||
|
||||
* @return an {@code OptionalLong} containing the minimum element of this
|
||||
* stream, or an empty {@code OptionalLong} if the stream is empty
|
||||
*/
|
||||
@ -488,7 +532,7 @@ public interface LongStream extends BaseStream<Long, LongStream> {
|
||||
/**
|
||||
* Returns an {@code OptionalLong} describing the maximum element of this
|
||||
* stream, or an empty optional if this stream is empty. This is a special
|
||||
* case of a <a href="package-summary.html#MutableReduction">reduction</a>
|
||||
* case of a <a href="package-summary.html#Reduction">reduction</a>
|
||||
* and is equivalent to:
|
||||
* <pre>{@code
|
||||
* return reduce(Long::max);
|
||||
@ -504,7 +548,7 @@ public interface LongStream extends BaseStream<Long, LongStream> {
|
||||
|
||||
/**
|
||||
* Returns the count of elements in this stream. This is a special case of
|
||||
* a <a href="package-summary.html#MutableReduction">reduction</a> and is
|
||||
* a <a href="package-summary.html#Reduction">reduction</a> and is
|
||||
* equivalent to:
|
||||
* <pre>{@code
|
||||
* return map(e -> 1L).sum();
|
||||
@ -520,7 +564,10 @@ public interface LongStream extends BaseStream<Long, LongStream> {
|
||||
* Returns an {@code OptionalDouble} describing the arithmetic mean of elements of
|
||||
* this stream, or an empty optional if this stream is empty. This is a
|
||||
* special case of a
|
||||
* <a href="package-summary.html#MutableReduction">reduction</a>.
|
||||
* <a href="package-summary.html#Reduction">reduction</a>.
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">terminal
|
||||
* operation</a>.
|
||||
*
|
||||
* @return an {@code OptionalDouble} containing the average element of this
|
||||
* stream, or an empty optional if the stream is empty
|
||||
@ -530,7 +577,10 @@ public interface LongStream extends BaseStream<Long, LongStream> {
|
||||
/**
|
||||
* Returns a {@code LongSummaryStatistics} describing various summary data
|
||||
* about the elements of this stream. This is a special case of a
|
||||
* <a href="package-summary.html#MutableReduction">reduction</a>.
|
||||
* <a href="package-summary.html#Reduction">reduction</a>.
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">terminal
|
||||
* operation</a>.
|
||||
*
|
||||
* @return a {@code LongSummaryStatistics} describing various summary data
|
||||
* about the elements of this stream
|
||||
@ -587,9 +637,8 @@ public interface LongStream extends BaseStream<Long, LongStream> {
|
||||
|
||||
/**
|
||||
* Returns an {@link OptionalLong} describing the first element of this
|
||||
* stream (in the encounter order), or an empty {@code OptionalLong} if the
|
||||
* stream is empty. If the stream has no encounter order, then any element
|
||||
* may be returned.
|
||||
* stream, or an empty {@code OptionalLong} if the stream is empty. If the
|
||||
* stream has no encounter order, then any element may be returned.
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
|
||||
* terminal operation</a>.
|
||||
@ -609,8 +658,8 @@ public interface LongStream extends BaseStream<Long, LongStream> {
|
||||
* <p>The behavior of this operation is explicitly nondeterministic; it is
|
||||
* free to select any element in the stream. This is to allow for maximal
|
||||
* performance in parallel operations; the cost is that multiple invocations
|
||||
* on the same source may not return the same result. (If the first element
|
||||
* in the encounter order is desired, use {@link #findFirst()} instead.)
|
||||
* on the same source may not return the same result. (If a stable result
|
||||
* is desired, use {@link #findFirst()} instead.)
|
||||
*
|
||||
* @return an {@code OptionalLong} describing some element of this stream,
|
||||
* or an empty {@code OptionalLong} if the stream is empty
|
||||
@ -622,6 +671,9 @@ public interface LongStream extends BaseStream<Long, LongStream> {
|
||||
* Returns a {@code DoubleStream} consisting of the elements of this stream,
|
||||
* converted to {@code double}.
|
||||
*
|
||||
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
|
||||
* operation</a>.
|
||||
*
|
||||
* @return a {@code DoubleStream} consisting of the elements of this stream,
|
||||
* converted to {@code double}
|
||||
*/
|
||||
@ -631,6 +683,9 @@ public interface LongStream extends BaseStream<Long, LongStream> {
|
||||
* Returns a {@code Stream} consisting of the elements of this stream,
|
||||
* each boxed to a {@code Long}.
|
||||
*
|
||||
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
|
||||
* operation</a>.
|
||||
*
|
||||
* @return a {@code Stream} consistent of the elements of this stream,
|
||||
* each boxed to {@code Long}
|
||||
*/
|
||||
@ -679,7 +734,7 @@ public interface LongStream extends BaseStream<Long, LongStream> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a sequential stream whose elements are the specified values.
|
||||
* Returns a sequential ordered stream whose elements are the specified values.
|
||||
*
|
||||
* @param values the elements of the new stream
|
||||
* @return the new stream
|
||||
@ -689,7 +744,7 @@ public interface LongStream extends BaseStream<Long, LongStream> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an infinite sequential {@code LongStream} produced by iterative
|
||||
* Returns an infinite sequential ordered {@code LongStream} produced by iterative
|
||||
* application of a function {@code f} to an initial element {@code seed},
|
||||
* producing a {@code Stream} consisting of {@code seed}, {@code f(seed)},
|
||||
* {@code f(f(seed))}, etc.
|
||||
@ -727,9 +782,9 @@ public interface LongStream extends BaseStream<Long, LongStream> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a sequential {@code LongStream} where each element is generated
|
||||
* by a {@code LongSupplier}. This is suitable for generating constant
|
||||
* streams, streams of random elements, etc.
|
||||
* Returns a sequential stream where each element is generated by
|
||||
* the provided {@code LongSupplier}. This is suitable for generating
|
||||
* constant streams, streams of random elements, etc.
|
||||
*
|
||||
* @param s the {@code LongSupplier} for generated elements
|
||||
* @return a new sequential {@code LongStream}
|
||||
@ -741,7 +796,7 @@ public interface LongStream extends BaseStream<Long, LongStream> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a sequential {@code LongStream} from {@code startInclusive}
|
||||
* Returns a sequential ordered {@code LongStream} from {@code startInclusive}
|
||||
* (inclusive) to {@code endExclusive} (exclusive) by an incremental step of
|
||||
* {@code 1}.
|
||||
*
|
||||
@ -774,7 +829,7 @@ public interface LongStream extends BaseStream<Long, LongStream> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a sequential {@code LongStream} from {@code startInclusive}
|
||||
* Returns a sequential ordered {@code LongStream} from {@code startInclusive}
|
||||
* (inclusive) to {@code endInclusive} (inclusive) by an incremental step of
|
||||
* {@code 1}.
|
||||
*
|
||||
@ -808,16 +863,16 @@ public interface LongStream extends BaseStream<Long, LongStream> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a lazy concatenated {@code LongStream} whose elements are all the
|
||||
* elements of a first {@code LongStream} succeeded by all the elements of the
|
||||
* second {@code LongStream}. The resulting stream is ordered if both
|
||||
* Creates a lazily concatenated stream whose elements are all the
|
||||
* elements of the first stream followed by all the elements of the
|
||||
* second stream. The resulting stream is ordered if both
|
||||
* of the input streams are ordered, and parallel if either of the input
|
||||
* streams is parallel. When the resulting stream is closed, the close
|
||||
* handlers for both input streams are invoked.
|
||||
*
|
||||
* @param a the first stream
|
||||
* @param b the second stream to concatenate on to end of the first stream
|
||||
* @return the concatenation of the two streams
|
||||
* @param b the second stream
|
||||
* @return the concatenation of the two input streams
|
||||
*/
|
||||
public static LongStream concat(LongStream a, LongStream b) {
|
||||
Objects.requireNonNull(a);
|
||||
@ -832,9 +887,9 @@ public interface LongStream extends BaseStream<Long, LongStream> {
|
||||
/**
|
||||
* A mutable builder for a {@code LongStream}.
|
||||
*
|
||||
* <p>A stream builder has a lifecycle, where it starts in a building
|
||||
* phase, during which elements can be added, and then transitions to a
|
||||
* built phase, after which elements may not be added. The built phase
|
||||
* <p>A stream builder has a lifecycle, which starts in a building
|
||||
* phase, during which elements can be added, and then transitions to a built
|
||||
* phase, after which elements may not be added. The built phase begins
|
||||
* begins when the {@link #build()} method is called, which creates an
|
||||
* ordered stream whose elements are the elements that were added to the
|
||||
* stream builder, in the order they were added.
|
||||
|
||||
@ -28,7 +28,7 @@ import java.util.Spliterator;
|
||||
import java.util.function.IntFunction;
|
||||
|
||||
/**
|
||||
* Helper class for executing <a href="package-summary.html#StreamPipelines">
|
||||
* Helper class for executing <a href="package-summary.html#StreamOps">
|
||||
* stream pipelines</a>, capturing all of the information about a stream
|
||||
* pipeline (output shape, intermediate operations, stream flags, parallelism,
|
||||
* etc) in one place.
|
||||
|
||||
@ -170,6 +170,7 @@ abstract class ReferencePipeline<P_IN, P_OUT>
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void accept(P_OUT u) {
|
||||
if (predicate.test(u))
|
||||
downstream.accept(u);
|
||||
@ -263,6 +264,7 @@ abstract class ReferencePipeline<P_IN, P_OUT>
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void accept(P_OUT u) {
|
||||
try (Stream<? extends R> result = mapper.apply(u)) {
|
||||
// We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it
|
||||
@ -360,16 +362,17 @@ abstract class ReferencePipeline<P_IN, P_OUT>
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Stream<P_OUT> peek(Consumer<? super P_OUT> tee) {
|
||||
Objects.requireNonNull(tee);
|
||||
public final Stream<P_OUT> peek(Consumer<? super P_OUT> action) {
|
||||
Objects.requireNonNull(action);
|
||||
return new StatelessOp<P_OUT, P_OUT>(this, StreamShape.REFERENCE,
|
||||
0) {
|
||||
@Override
|
||||
Sink<P_OUT> opWrapSink(int flags, Sink<P_OUT> sink) {
|
||||
return new Sink.ChainedReference<P_OUT, P_OUT>(sink) {
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void accept(P_OUT u) {
|
||||
tee.accept(u);
|
||||
action.accept(u);
|
||||
downstream.accept(u);
|
||||
}
|
||||
};
|
||||
@ -515,10 +518,10 @@ abstract class ReferencePipeline<P_IN, P_OUT>
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <R> R collect(Supplier<R> resultFactory,
|
||||
public final <R> R collect(Supplier<R> supplier,
|
||||
BiConsumer<R, ? super P_OUT> accumulator,
|
||||
BiConsumer<R, R> combiner) {
|
||||
return evaluate(ReduceOps.makeRef(resultFactory, accumulator, combiner));
|
||||
return evaluate(ReduceOps.makeRef(supplier, accumulator, combiner));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -24,13 +24,18 @@
|
||||
*/
|
||||
package java.util.stream;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Spliterator;
|
||||
import java.util.Spliterators;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.BinaryOperator;
|
||||
@ -44,51 +49,90 @@ import java.util.function.ToIntFunction;
|
||||
import java.util.function.ToLongFunction;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
// @@@ Specification to-do list @@@
|
||||
// - Describe the difference between sequential and parallel streams
|
||||
// - More general information about reduce, better definitions for associativity, more description of
|
||||
// how reduce employs parallelism, more examples
|
||||
// - Role of stream flags in various operations, specifically ordering
|
||||
// - Whether each op preserves encounter order
|
||||
// @@@ Specification to-do list @@@
|
||||
|
||||
/**
|
||||
* A sequence of elements supporting sequential and parallel bulk operations.
|
||||
* Streams support lazy intermediate operations (transforming a stream to
|
||||
* another stream) such as {@code filter} and {@code map}, and terminal
|
||||
* operations (consuming the contents of a stream to produce a result or
|
||||
* side-effect), such as {@code forEach}, {@code findFirst}, and {@code
|
||||
* iterator}. Once an operation has been performed on a stream, it
|
||||
* is considered <em>consumed</em> and no longer usable for other operations.
|
||||
* A sequence of elements supporting sequential and parallel aggregate
|
||||
* operations. The following example illustrates an aggregate operation using
|
||||
* {@link Stream} and {@link IntStream}:
|
||||
*
|
||||
* <p>For sequential stream pipelines, all operations are performed in the
|
||||
* <a href="package-summary.html#Ordering">encounter order</a> of the pipeline
|
||||
* source, if the pipeline source has a defined encounter order.
|
||||
* <pre>{@code
|
||||
* int sum = widgets.stream()
|
||||
* .filter(w -> w.getColor() == RED)
|
||||
* .mapToInt(w -> w.getWeight())
|
||||
* .sum();
|
||||
* }</pre>
|
||||
*
|
||||
* <p>For parallel stream pipelines, unless otherwise specified, intermediate
|
||||
* stream operations preserve the <a href="package-summary.html#Ordering">
|
||||
* encounter order</a> of their source, and terminal operations
|
||||
* respect the encounter order of their source, if the source
|
||||
* has an encounter order. Provided that and parameters to stream operations
|
||||
* satisfy the <a href="package-summary.html#NonInterference">non-interference
|
||||
* requirements</a>, and excepting differences arising from the absence of
|
||||
* a defined encounter order, the result of a stream pipeline should be the
|
||||
* stable across multiple executions of the same operations on the same source.
|
||||
* However, the timing and thread in which side-effects occur (for those
|
||||
* operations which are allowed to produce side-effects, such as
|
||||
* {@link #forEach(Consumer)}), are explicitly nondeterministic for parallel
|
||||
* execution of stream pipelines.
|
||||
* In this example, {@code widgets} is a {@code Collection<Widget>}. We create
|
||||
* a stream of {@code Widget} objects via {@link Collection#stream Collection.stream()},
|
||||
* filter it to produce a stream containing only the red widgets, and then
|
||||
* transform it into a stream of {@code int} values representing the weight of
|
||||
* each red widget. Then this stream is summed to produce a total weight.
|
||||
*
|
||||
* <p>Unless otherwise noted, passing a {@code null} argument to any stream
|
||||
* method may result in a {@link NullPointerException}.
|
||||
* <p>To perform a computation, stream
|
||||
* <a href="package-summary.html#StreamOps">operations</a> are composed into a
|
||||
* <em>stream pipeline</em>. A stream pipeline consists of a source (which
|
||||
* might be an array, a collection, a generator function, an I/O channel,
|
||||
* etc), zero or more <em>intermediate operations</em> (which transform a
|
||||
* stream into another stream, such as {@link Stream#filter(Predicate)}), and a
|
||||
* <em>terminal operation</em> (which produces a result or side-effect, such
|
||||
* as {@link Stream#count()} or {@link Stream#forEach(Consumer)}).
|
||||
* Streams are lazy; computation on the source data is only performed when the
|
||||
* terminal operation is initiated, and source elements are consumed only
|
||||
* as needed.
|
||||
*
|
||||
* @apiNote
|
||||
* Streams are not data structures; they do not manage the storage for their
|
||||
* elements, nor do they support access to individual elements. However,
|
||||
* you can use the {@link #iterator()} or {@link #spliterator()} operations to
|
||||
* perform a controlled traversal.
|
||||
* <p>Collections and streams, while bearing some superficial similarities,
|
||||
* have different goals. Collections are primarily concerned with the efficient
|
||||
* management of, and access to, their elements. By contrast, streams do not
|
||||
* provide a means to directly access or manipulate their elements, and are
|
||||
* instead concerned with declaratively describing their source and the
|
||||
* computational operations which will be performed in aggregate on that source.
|
||||
* However, if the provided stream operations do not offer the desired
|
||||
* functionality, the {@link #iterator()} and {@link #spliterator()} operations
|
||||
* can be used to perform a controlled traversal.
|
||||
*
|
||||
* @param <T> type of elements
|
||||
* <p>A stream pipeline, like the "widgets" example above, can be viewed as
|
||||
* a <em>query</em> on the stream source. Unless the source was explicitly
|
||||
* designed for concurrent modification (such as a {@link ConcurrentHashMap}),
|
||||
* unpredictable or erroneous behavior may result from modifying the stream
|
||||
* source while it is being queried.
|
||||
*
|
||||
* <p>Most stream operations accept parameters that describe user-specified
|
||||
* behavior, such as the lambda expression {@code w -> w.getWeight()} passed to
|
||||
* {@code mapToInt} in the example above. Such parameters are always instances
|
||||
* of a <a href="../function/package-summary.html">functional interface</a> such
|
||||
* as {@link java.util.function.Function}, and are often lambda expressions or
|
||||
* method references. These parameters can never be null, should not modify the
|
||||
* stream source, and should be
|
||||
* <a href="package-summary.html#NonInterference">effectively stateless</a>
|
||||
* (their result should not depend on any state that might change during
|
||||
* execution of the stream pipeline.)
|
||||
*
|
||||
* <p>A stream should be operated on (invoking an intermediate or terminal stream
|
||||
* operation) only once. This rules out, for example, "forked" streams, where
|
||||
* the same source feeds two or more pipelines, or multiple traversals of the
|
||||
* same stream. A stream implementation may throw {@link IllegalStateException}
|
||||
* if it detects that the stream is being reused. However, since some stream
|
||||
* operations may return their receiver rather than a new stream object, it may
|
||||
* not be possible to detect reuse in all cases.
|
||||
*
|
||||
* <p>Streams have a {@link #close()} method and implement {@link AutoCloseable},
|
||||
* but nearly all stream instances do not actually need to be closed after use.
|
||||
* Generally, only streams whose source is an IO channel (such as those returned
|
||||
* by {@link Files#lines(Path, Charset)}) will require closing. Most streams
|
||||
* are backed by collections, arrays, or generating functions, which require no
|
||||
* special resource management. (If a stream does require closing, it can be
|
||||
* declared as a resource in a {@code try}-with-resources statement.)
|
||||
*
|
||||
* <p>Stream pipelines may execute either sequentially or in
|
||||
* <a href="package-summary.html#Parallelism">parallel</a>. This
|
||||
* execution mode is a property of the stream. Streams are created
|
||||
* with an initial choice of sequential or parallel execution. (For example,
|
||||
* {@link Collection#stream() Collection.stream()} creates a sequential stream,
|
||||
* and {@link Collection#parallelStream() Collection.parallelStream()} creates
|
||||
* a parallel one.) This choice of execution mode may be modified by the
|
||||
* {@link #sequential()} or {@link #parallel()} methods, and may be queried with
|
||||
* the {@link #isParallel()} method.
|
||||
*
|
||||
* @param <T> the type of the stream elements
|
||||
* @since 1.8
|
||||
* @see <a href="package-summary.html">java.util.stream</a>
|
||||
*/
|
||||
@ -168,9 +212,9 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
||||
/**
|
||||
* Returns a stream consisting of the results of replacing each element of
|
||||
* this stream with the contents of the stream produced by applying the
|
||||
* provided mapping function to each element. If the result of the mapping
|
||||
* function is {@code null}, this is treated as if the result is an empty
|
||||
* stream.
|
||||
* provided mapping function to each element. (If the result of the mapping
|
||||
* function is {@code null}, this is treated as if the result was an empty
|
||||
* stream.)
|
||||
*
|
||||
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
|
||||
* operation</a>.
|
||||
@ -197,9 +241,9 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
||||
/**
|
||||
* Returns an {@code IntStream} consisting of the results of replacing each
|
||||
* element of this stream with the contents of the stream produced by
|
||||
* applying the provided mapping function to each element. If the result of
|
||||
* the mapping function is {@code null}, this is treated as if the result is
|
||||
* an empty stream.
|
||||
* applying the provided mapping function to each element. (If the result
|
||||
* of the mapping function is {@code null}, this is treated as if the result
|
||||
* was an empty stream.)
|
||||
*
|
||||
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
|
||||
* operation</a>.
|
||||
@ -214,9 +258,9 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
||||
/**
|
||||
* Returns a {@code LongStream} consisting of the results of replacing each
|
||||
* element of this stream with the contents of the stream produced
|
||||
* by applying the provided mapping function to each element. If the result
|
||||
* of the mapping function is {@code null}, this is treated as if the
|
||||
* result is an empty stream.
|
||||
* by applying the provided mapping function to each element. (If the result
|
||||
* of the mapping function is {@code null}, this is treated as if the result
|
||||
* was an empty stream.)
|
||||
*
|
||||
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
|
||||
* operation</a>.
|
||||
@ -231,9 +275,9 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
||||
/**
|
||||
* Returns a {@code DoubleStream} consisting of the results of replacing each
|
||||
* element of this stream with the contents of the stream produced
|
||||
* by applying the provided mapping function to each element. If the result
|
||||
* by applying the provided mapping function to each element. (If the result
|
||||
* of the mapping function is {@code null}, this is treated as if the result
|
||||
* is an empty stream.
|
||||
* was an empty stream.)
|
||||
*
|
||||
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
|
||||
* operation</a>.
|
||||
@ -260,7 +304,7 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
||||
* Returns a stream consisting of the elements of this stream, sorted
|
||||
* according to natural order. If the elements of this stream are not
|
||||
* {@code Comparable}, a {@code java.lang.ClassCastException} may be thrown
|
||||
* when the stream pipeline is executed.
|
||||
* when the terminal operation is executed.
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">stateful
|
||||
* intermediate operation</a>.
|
||||
@ -301,18 +345,18 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
||||
* <pre>{@code
|
||||
* list.stream()
|
||||
* .filter(filteringFunction)
|
||||
* .peek(e -> {System.out.println("Filtered value: " + e); });
|
||||
* .peek(e -> System.out.println("Filtered value: " + e));
|
||||
* .map(mappingFunction)
|
||||
* .peek(e -> {System.out.println("Mapped value: " + e); });
|
||||
* .peek(e -> System.out.println("Mapped value: " + e));
|
||||
* .collect(Collectors.intoList());
|
||||
* }</pre>
|
||||
*
|
||||
* @param consumer a <a href="package-summary.html#NonInterference">
|
||||
* @param action a <a href="package-summary.html#NonInterference">
|
||||
* non-interfering</a> action to perform on the elements as
|
||||
* they are consumed from the stream
|
||||
* @return the new stream
|
||||
*/
|
||||
Stream<T> peek(Consumer<? super T> consumer);
|
||||
Stream<T> peek(Consumer<? super T> action);
|
||||
|
||||
/**
|
||||
* Returns a stream consisting of the elements of this stream, truncated
|
||||
@ -329,8 +373,8 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
||||
|
||||
/**
|
||||
* Returns a stream consisting of the remaining elements of this stream
|
||||
* after indexing {@code startInclusive} elements into the stream. If the
|
||||
* {@code startInclusive} index lies past the end of this stream then an
|
||||
* after discarding the first {@code startInclusive} elements of the stream.
|
||||
* If this stream contains fewer than {@code startInclusive} elements then an
|
||||
* empty stream will be returned.
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">stateful
|
||||
@ -344,10 +388,10 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
||||
|
||||
/**
|
||||
* Returns a stream consisting of the remaining elements of this stream
|
||||
* after indexing {@code startInclusive} elements into the stream and
|
||||
* truncated to contain no more than {@code endExclusive - startInclusive}
|
||||
* elements. If the {@code startInclusive} index lies past the end
|
||||
* of this stream then an empty stream will be returned.
|
||||
* after discarding the first {@code startInclusive} elements and truncating
|
||||
* the result to be no longer than {@code endExclusive - startInclusive}
|
||||
* elements in length. If this stream contains fewer than
|
||||
* {@code startInclusive} elements then an empty stream will be returned.
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
|
||||
* stateful intermediate operation</a>.
|
||||
@ -405,11 +449,23 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
||||
|
||||
/**
|
||||
* Returns an array containing the elements of this stream, using the
|
||||
* provided {@code generator} function to allocate the returned array.
|
||||
* provided {@code generator} function to allocate the returned array, as
|
||||
* well as any additional arrays that might be required for a partitioned
|
||||
* execution or for resizing.
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">terminal
|
||||
* operation</a>.
|
||||
*
|
||||
* @apiNote
|
||||
* The generator function takes an integer, which is the size of the
|
||||
* desired array, and produces an array of the desired size. This can be
|
||||
* concisely expressed with an array constructor reference:
|
||||
* <pre>{@code
|
||||
* Person[] men = people.stream()
|
||||
* .filter(p -> p.getGender() == MALE)
|
||||
* .toArray(Person[]::new);
|
||||
* }</pre>
|
||||
*
|
||||
* @param <A> the element type of the resulting array
|
||||
* @param generator a function which produces a new array of the desired
|
||||
* type and the provided length
|
||||
@ -451,7 +507,7 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
||||
* Integer sum = integers.reduce(0, (a, b) -> a+b);
|
||||
* }</pre>
|
||||
*
|
||||
* or more compactly:
|
||||
* or:
|
||||
*
|
||||
* <pre>{@code
|
||||
* Integer sum = integers.reduce(0, Integer::sum);
|
||||
@ -501,7 +557,8 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
||||
* @param accumulator an <a href="package-summary.html#Associativity">associative</a>
|
||||
* <a href="package-summary.html#NonInterference">non-interfering,
|
||||
* stateless</a> function for combining two values
|
||||
* @return the result of the reduction
|
||||
* @return an {@link Optional} describing the result of the reduction
|
||||
* @throws NullPointerException if the result of the reduction is null
|
||||
* @see #reduce(Object, BinaryOperator)
|
||||
* @see #min(java.util.Comparator)
|
||||
* @see #max(java.util.Comparator)
|
||||
@ -511,7 +568,7 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
||||
/**
|
||||
* Performs a <a href="package-summary.html#Reduction">reduction</a> on the
|
||||
* elements of this stream, using the provided identity, accumulation
|
||||
* function, and a combining functions. This is equivalent to:
|
||||
* function, and combining functions. This is equivalent to:
|
||||
* <pre>{@code
|
||||
* U result = identity;
|
||||
* for (T element : this stream)
|
||||
@ -537,8 +594,8 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
||||
* by an explicit combination of {@code map} and {@code reduce} operations.
|
||||
* The {@code accumulator} function acts as a fused mapper and accumulator,
|
||||
* which can sometimes be more efficient than separate mapping and reduction,
|
||||
* such as in the case where knowing the previously reduced value allows you
|
||||
* to avoid some computation.
|
||||
* such as when knowing the previously reduced value allows you to avoid
|
||||
* some computation.
|
||||
*
|
||||
* @param <U> The type of the result
|
||||
* @param identity the identity value for the combiner function
|
||||
@ -561,12 +618,12 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
||||
/**
|
||||
* Performs a <a href="package-summary.html#MutableReduction">mutable
|
||||
* reduction</a> operation on the elements of this stream. A mutable
|
||||
* reduction is one in which the reduced value is a mutable value holder,
|
||||
* reduction is one in which the reduced value is a mutable result container,
|
||||
* such as an {@code ArrayList}, and elements are incorporated by updating
|
||||
* the state of the result, rather than by replacing the result. This
|
||||
* the state of the result rather than by replacing the result. This
|
||||
* produces a result equivalent to:
|
||||
* <pre>{@code
|
||||
* R result = resultFactory.get();
|
||||
* R result = supplier.get();
|
||||
* for (T element : this stream)
|
||||
* accumulator.accept(result, element);
|
||||
* return result;
|
||||
@ -579,10 +636,11 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
||||
* operation</a>.
|
||||
*
|
||||
* @apiNote There are many existing classes in the JDK whose signatures are
|
||||
* a good match for use as arguments to {@code collect()}. For example,
|
||||
* the following will accumulate strings into an ArrayList:
|
||||
* well-suited for use with method references as arguments to {@code collect()}.
|
||||
* For example, the following will accumulate strings into an {@code ArrayList}:
|
||||
* <pre>{@code
|
||||
* List<String> asList = stringStream.collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
|
||||
* List<String> asList = stringStream.collect(ArrayList::new, ArrayList::add,
|
||||
* ArrayList::addAll);
|
||||
* }</pre>
|
||||
*
|
||||
* <p>The following will take a stream of strings and concatenates them into a
|
||||
@ -594,10 +652,9 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
||||
* }</pre>
|
||||
*
|
||||
* @param <R> type of the result
|
||||
* @param resultFactory a function that creates a new result container.
|
||||
* For a parallel execution, this function may be
|
||||
* called multiple times and must return a fresh value
|
||||
* each time.
|
||||
* @param supplier a function that creates a new result container. For a
|
||||
* parallel execution, this function may be called
|
||||
* multiple times and must return a fresh value each time.
|
||||
* @param accumulator an <a href="package-summary.html#Associativity">associative</a>
|
||||
* <a href="package-summary.html#NonInterference">non-interfering,
|
||||
* stateless</a> function for incorporating an additional
|
||||
@ -608,24 +665,24 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
||||
* must be compatible with the accumulator function
|
||||
* @return the result of the reduction
|
||||
*/
|
||||
<R> R collect(Supplier<R> resultFactory,
|
||||
<R> R collect(Supplier<R> supplier,
|
||||
BiConsumer<R, ? super T> accumulator,
|
||||
BiConsumer<R, R> combiner);
|
||||
|
||||
/**
|
||||
* Performs a <a href="package-summary.html#MutableReduction">mutable
|
||||
* reduction</a> operation on the elements of this stream using a
|
||||
* {@code Collector} object to describe the reduction. A {@code Collector}
|
||||
* {@code Collector}. A {@code Collector}
|
||||
* encapsulates the functions used as arguments to
|
||||
* {@link #collect(Supplier, BiConsumer, BiConsumer)}, allowing for reuse of
|
||||
* collection strategies, and composition of collect operations such as
|
||||
* collection strategies and composition of collect operations such as
|
||||
* multiple-level grouping or partitioning.
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">terminal
|
||||
* operation</a>.
|
||||
*
|
||||
* <p>When executed in parallel, multiple intermediate results may be
|
||||
* instantiated, populated, and merged, so as to maintain isolation of
|
||||
* instantiated, populated, and merged so as to maintain isolation of
|
||||
* mutable data structures. Therefore, even when executed in parallel
|
||||
* with non-thread-safe data structures (such as {@code ArrayList}), no
|
||||
* additional synchronization is needed for a parallel reduction.
|
||||
@ -638,16 +695,16 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
||||
*
|
||||
* <p>The following will classify {@code Person} objects by city:
|
||||
* <pre>{@code
|
||||
* Map<String, Collection<Person>> peopleByCity
|
||||
* = personStream.collect(Collectors.groupBy(Person::getCity));
|
||||
* Map<String, List<Person>> peopleByCity
|
||||
* = personStream.collect(Collectors.groupingBy(Person::getCity));
|
||||
* }</pre>
|
||||
*
|
||||
* <p>The following will classify {@code Person} objects by state and city,
|
||||
* cascading two {@code Collector}s together:
|
||||
* <pre>{@code
|
||||
* Map<String, Map<String, Collection<Person>>> peopleByStateAndCity
|
||||
* = personStream.collect(Collectors.groupBy(Person::getState,
|
||||
* Collectors.groupBy(Person::getCity)));
|
||||
* Map<String, Map<String, List<Person>>> peopleByStateAndCity
|
||||
* = personStream.collect(Collectors.groupingBy(Person::getState,
|
||||
* Collectors.groupingBy(Person::getCity)));
|
||||
* }</pre>
|
||||
*
|
||||
* @param <R> the type of the result
|
||||
@ -662,7 +719,7 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
||||
/**
|
||||
* Returns the minimum element of this stream according to the provided
|
||||
* {@code Comparator}. This is a special case of a
|
||||
* <a href="package-summary.html#MutableReduction">reduction</a>.
|
||||
* <a href="package-summary.html#Reduction">reduction</a>.
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">terminal operation</a>.
|
||||
*
|
||||
@ -671,13 +728,14 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
||||
* elements of this stream
|
||||
* @return an {@code Optional} describing the minimum element of this stream,
|
||||
* or an empty {@code Optional} if the stream is empty
|
||||
* @throws NullPointerException if the minimum element is null
|
||||
*/
|
||||
Optional<T> min(Comparator<? super T> comparator);
|
||||
|
||||
/**
|
||||
* Returns the maximum element of this stream according to the provided
|
||||
* {@code Comparator}. This is a special case of a
|
||||
* <a href="package-summary.html#MutableReduction">reduction</a>.
|
||||
* <a href="package-summary.html#Reduction">reduction</a>.
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">terminal
|
||||
* operation</a>.
|
||||
@ -687,12 +745,13 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
||||
* elements of this stream
|
||||
* @return an {@code Optional} describing the maximum element of this stream,
|
||||
* or an empty {@code Optional} if the stream is empty
|
||||
* @throws NullPointerException if the maximum element is null
|
||||
*/
|
||||
Optional<T> max(Comparator<? super T> comparator);
|
||||
|
||||
/**
|
||||
* Returns the count of elements in this stream. This is a special case of
|
||||
* a <a href="package-summary.html#MutableReduction">reduction</a> and is
|
||||
* a <a href="package-summary.html#Reduction">reduction</a> and is
|
||||
* equivalent to:
|
||||
* <pre>{@code
|
||||
* return mapToLong(e -> 1L).sum();
|
||||
@ -753,10 +812,9 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
||||
boolean noneMatch(Predicate<? super T> predicate);
|
||||
|
||||
/**
|
||||
* Returns an {@link Optional} describing the first element of this stream
|
||||
* (in the encounter order), or an empty {@code Optional} if the stream is
|
||||
* empty. If the stream has no encounter order, then any element may be
|
||||
* returned.
|
||||
* Returns an {@link Optional} describing the first element of this stream,
|
||||
* or an empty {@code Optional} if the stream is empty. If the stream has
|
||||
* no encounter order, then any element may be returned.
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
|
||||
* terminal operation</a>.
|
||||
@ -777,8 +835,8 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
||||
* <p>The behavior of this operation is explicitly nondeterministic; it is
|
||||
* free to select any element in the stream. This is to allow for maximal
|
||||
* performance in parallel operations; the cost is that multiple invocations
|
||||
* on the same source may not return the same result. (If the first element
|
||||
* in the encounter order is desired, use {@link #findFirst()} instead.)
|
||||
* on the same source may not return the same result. (If a stable result
|
||||
* is desired, use {@link #findFirst()} instead.)
|
||||
*
|
||||
* @return an {@code Optional} describing some element of this stream, or an
|
||||
* empty {@code Optional} if the stream is empty
|
||||
@ -821,20 +879,20 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a sequential stream whose elements are the specified values.
|
||||
* Returns a sequential ordered stream whose elements are the specified values.
|
||||
*
|
||||
* @param <T> the type of stream elements
|
||||
* @param values the elements of the new stream
|
||||
* @return the new stream
|
||||
*/
|
||||
@SafeVarargs
|
||||
@SuppressWarnings("varargs") // Creating a stream from an array is safe
|
||||
@SuppressWarnings("varargs")
|
||||
public static<T> Stream<T> of(T... values) {
|
||||
return Arrays.stream(values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an infinite sequential {@code Stream} produced by iterative
|
||||
* Returns an infinite sequential ordered {@code Stream} produced by iterative
|
||||
* application of a function {@code f} to an initial element {@code seed},
|
||||
* producing a {@code Stream} consisting of {@code seed}, {@code f(seed)},
|
||||
* {@code f(f(seed))}, etc.
|
||||
@ -872,8 +930,8 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a sequential {@code Stream} where each element is
|
||||
* generated by a {@code Supplier}. This is suitable for generating
|
||||
* Returns a sequential stream where each element is generated by
|
||||
* the provided {@code Supplier}. This is suitable for generating
|
||||
* constant streams, streams of random elements, etc.
|
||||
*
|
||||
* @param <T> the type of stream elements
|
||||
@ -887,17 +945,16 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a lazy concatenated {@code Stream} whose elements are all the
|
||||
* elements of a first {@code Stream} succeeded by all the elements of the
|
||||
* second {@code Stream}. The resulting stream is ordered if both
|
||||
* Creates a lazily concatenated stream whose elements are all the
|
||||
* elements of the first stream followed by all the elements of the
|
||||
* second stream. The resulting stream is ordered if both
|
||||
* of the input streams are ordered, and parallel if either of the input
|
||||
* streams is parallel. When the resulting stream is closed, the close
|
||||
* handlers for both input streams are invoked.
|
||||
*
|
||||
* @param <T> The type of stream elements
|
||||
* @param a the first stream
|
||||
* @param b the second stream to concatenate on to end of the first
|
||||
* stream
|
||||
* @param b the second stream
|
||||
* @return the concatenation of the two input streams
|
||||
*/
|
||||
public static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b) {
|
||||
@ -917,7 +974,7 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
||||
* {@code Builder} (without the copying overhead that comes from using
|
||||
* an {@code ArrayList} as a temporary buffer.)
|
||||
*
|
||||
* <p>A {@code Stream.Builder} has a lifecycle, where it starts in a building
|
||||
* <p>A stream builder has a lifecycle, which starts in a building
|
||||
* phase, during which elements can be added, and then transitions to a built
|
||||
* phase, after which elements may not be added. The built phase begins
|
||||
* when the {@link #build()} method is called, which creates an ordered
|
||||
|
||||
@ -1456,4 +1456,5 @@ class StreamSpliterators {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -32,12 +32,8 @@ import java.util.function.Supplier;
|
||||
* Low-level utility methods for creating and manipulating streams.
|
||||
*
|
||||
* <p>This class is mostly for library writers presenting stream views
|
||||
* of their data structures; most static stream methods for end users are in
|
||||
* {@link Streams}.
|
||||
*
|
||||
* <p>Unless otherwise stated, streams are created as sequential
|
||||
* streams. A sequential stream can be transformed into a parallel stream by
|
||||
* calling the {@code parallel()} method on the created stream.
|
||||
* of data structures; most static stream methods intended for end users are in
|
||||
* the various {@code Stream} classes.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
@ -80,7 +76,7 @@ public final class StreamSupport {
|
||||
* {@code Supplier} of {@code Spliterator}.
|
||||
*
|
||||
* <p>The {@link Supplier#get()} method will be invoked on the supplier no
|
||||
* more than once, and after the terminal operation of the stream pipeline
|
||||
* more than once, and only after the terminal operation of the stream pipeline
|
||||
* commences.
|
||||
*
|
||||
* <p>For spliterators that report a characteristic of {@code IMMUTABLE}
|
||||
@ -88,7 +84,7 @@ public final class StreamSupport {
|
||||
* <a href="../Spliterator.html#binding">late-binding</a>, it is likely
|
||||
* more efficient to use {@link #stream(java.util.Spliterator, boolean)}
|
||||
* instead.
|
||||
* The use of a {@code Supplier} in this form provides a level of
|
||||
* <p>The use of a {@code Supplier} in this form provides a level of
|
||||
* indirection that reduces the scope of potential interference with the
|
||||
* source. Since the supplier is only invoked after the terminal operation
|
||||
* commences, any modifications to the source up to the start of the
|
||||
@ -148,7 +144,7 @@ public final class StreamSupport {
|
||||
* {@code Supplier} of {@code Spliterator.OfInt}.
|
||||
*
|
||||
* <p>The {@link Supplier#get()} method will be invoked on the supplier no
|
||||
* more than once, and after the terminal operation of the stream pipeline
|
||||
* more than once, and only after the terminal operation of the stream pipeline
|
||||
* commences.
|
||||
*
|
||||
* <p>For spliterators that report a characteristic of {@code IMMUTABLE}
|
||||
@ -156,7 +152,7 @@ public final class StreamSupport {
|
||||
* <a href="../Spliterator.html#binding">late-binding</a>, it is likely
|
||||
* more efficient to use {@link #intStream(java.util.Spliterator.OfInt, boolean)}
|
||||
* instead.
|
||||
* The use of a {@code Supplier} in this form provides a level of
|
||||
* <p>The use of a {@code Supplier} in this form provides a level of
|
||||
* indirection that reduces the scope of potential interference with the
|
||||
* source. Since the supplier is only invoked after the terminal operation
|
||||
* commences, any modifications to the source up to the start of the
|
||||
@ -215,7 +211,7 @@ public final class StreamSupport {
|
||||
* {@code Supplier} of {@code Spliterator.OfLong}.
|
||||
*
|
||||
* <p>The {@link Supplier#get()} method will be invoked on the supplier no
|
||||
* more than once, and after the terminal operation of the stream pipeline
|
||||
* more than once, and only after the terminal operation of the stream pipeline
|
||||
* commences.
|
||||
*
|
||||
* <p>For spliterators that report a characteristic of {@code IMMUTABLE}
|
||||
@ -223,7 +219,7 @@ public final class StreamSupport {
|
||||
* <a href="../Spliterator.html#binding">late-binding</a>, it is likely
|
||||
* more efficient to use {@link #longStream(java.util.Spliterator.OfLong, boolean)}
|
||||
* instead.
|
||||
* The use of a {@code Supplier} in this form provides a level of
|
||||
* <p>The use of a {@code Supplier} in this form provides a level of
|
||||
* indirection that reduces the scope of potential interference with the
|
||||
* source. Since the supplier is only invoked after the terminal operation
|
||||
* commences, any modifications to the source up to the start of the
|
||||
@ -282,7 +278,7 @@ public final class StreamSupport {
|
||||
* {@code Supplier} of {@code Spliterator.OfDouble}.
|
||||
*
|
||||
* <p>The {@link Supplier#get()} method will be invoked on the supplier no
|
||||
* more than once, and after the terminal operation of the stream pipeline
|
||||
* more than once, and only after the terminal operation of the stream pipeline
|
||||
* commences.
|
||||
*
|
||||
* <p>For spliterators that report a characteristic of {@code IMMUTABLE}
|
||||
@ -290,7 +286,7 @@ public final class StreamSupport {
|
||||
* <a href="../Spliterator.html#binding">late-binding</a>, it is likely
|
||||
* more efficient to use {@link #doubleStream(java.util.Spliterator.OfDouble, boolean)}
|
||||
* instead.
|
||||
* The use of a {@code Supplier} in this form provides a level of
|
||||
* <p>The use of a {@code Supplier} in this form provides a level of
|
||||
* indirection that reduces the scope of potential interference with the
|
||||
* source. Since the supplier is only invoked after the terminal operation
|
||||
* commences, any modifications to the source up to the start of the
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user