提交 f884bcee 编写于 作者: H henryjen

8025909: Lambda Library Spec Updates

8024179: Document limitations and performance characteristics of stream sources and operations
8024138: (Spec clarification) Lambda Metafacory spec should state DMH constraint on implMethod
Reviewed-by: mduigou
Contributed-by: brian.goetz@oracle.com, paul.sandoz@oracle.com
上级 0cfffffa
...@@ -51,10 +51,12 @@ public interface Iterable<T> { ...@@ -51,10 +51,12 @@ public interface Iterable<T> {
Iterator<T> iterator(); Iterator<T> iterator();
/** /**
* Performs the given action on the contents of the {@code Iterable}, in the * Performs the given action for each element of the {@code Iterable}
* order elements occur when iterating, until all elements have been * until all elements have been processed or the action throws an
* processed or the action throws an exception. Errors or runtime * exception. Unless otherwise specified by the implementing class,
* exceptions thrown by the action are relayed to the caller. * actions are performed in the order of iteration (if an iteration order
* is specified). Exceptions thrown by the action are relayed to the
* caller.
* *
* @implSpec * @implSpec
* <p>The default implementation behaves as if: * <p>The default implementation behaves as if:
......
...@@ -183,15 +183,15 @@ public class LambdaMetafactory { ...@@ -183,15 +183,15 @@ public class LambdaMetafactory {
* @param samMethodType MethodType of the method in the functional interface * @param samMethodType MethodType of the method in the functional interface
* to which the lambda or method reference is being * to which the lambda or method reference is being
* converted, represented as a MethodType. * converted, represented as a MethodType.
* @param implMethod The implementation method which should be called * @param implMethod A direct method handle describing the implementation
* (with suitable adaptation of argument types, return * method which should be called (with suitable adaptation
* types, and adjustment for captured arguments) when * of argument types, return types, and adjustment for
* methods of the resulting functional interface instance * captured arguments) when methods of the resulting
* are invoked. * functional interface instance are invoked.
* @param instantiatedMethodType The signature of the primary functional * @param instantiatedMethodType The signature of the primary functional
* interface method after type variables * interface method after type variables
* are substituted with their instantiation * are substituted with their instantiation
* from the capture site * from the capture site.
* @return a CallSite, which, when invoked, will return an instance of the * @return a CallSite, which, when invoked, will return an instance of the
* functional interface * functional interface
* @throws ReflectiveOperationException if the caller is not able to * @throws ReflectiveOperationException if the caller is not able to
...@@ -220,15 +220,21 @@ public class LambdaMetafactory { ...@@ -220,15 +220,21 @@ public class LambdaMetafactory {
* references to functional interfaces, which supports serialization and * references to functional interfaces, which supports serialization and
* other uncommon options. * other uncommon options.
* *
* The declared argument list for this method is: * <p>The declared argument list for this method is:
* *
* <pre>{@code
* CallSite altMetafactory(MethodHandles.Lookup caller, * CallSite altMetafactory(MethodHandles.Lookup caller,
* String invokedName, * String invokedName,
* MethodType invokedType, * MethodType invokedType,
* Object... args) * Object... args)
* }</pre>
* *
* but it behaves as if the argument list is: * <p>but it behaves as if the argument list is as follows, where names that
* appear in the argument list for
* {@link #metafactory(MethodHandles.Lookup, String, MethodType, MethodType, MethodHandle, MethodType)}
* have the same specification as in that method:
* *
* <pre>{@code
* CallSite altMetafactory(MethodHandles.Lookup caller, * CallSite altMetafactory(MethodHandles.Lookup caller,
* String invokedName, * String invokedName,
* MethodType invokedType, * MethodType invokedType,
...@@ -241,7 +247,15 @@ public class LambdaMetafactory { ...@@ -241,7 +247,15 @@ public class LambdaMetafactory {
* int bridgeCount, // IF flags has BRIDGES set * int bridgeCount, // IF flags has BRIDGES set
* MethodType... bridges // IF flags has BRIDGES set * MethodType... bridges // IF flags has BRIDGES set
* ) * )
* }</pre>
* *
* <p>If the flags contains {@code FLAG_SERIALIZABLE}, or one of the marker
* interfaces extends {@link Serializable}, the metafactory will link the
* call site to one that produces a serializable lambda. In addition to
* the lambda instance implementing {@code Serializable}, it will have a
* {@code writeReplace} method that returns an appropriate {@link
* SerializedLambda}, and an appropriate {@code $deserializeLambda$}
* method.
* *
* @param caller Stacked automatically by VM; represents a lookup context * @param caller Stacked automatically by VM; represents a lookup context
* with the accessibility privileges of the caller. * with the accessibility privileges of the caller.
...@@ -257,7 +271,7 @@ public class LambdaMetafactory { ...@@ -257,7 +271,7 @@ public class LambdaMetafactory {
* In the event that the implementation method is an * In the event that the implementation method is an
* instance method, the first argument in the invocation * instance method, the first argument in the invocation
* signature will correspond to the receiver. * signature will correspond to the receiver.
* @param args flags and optional arguments, as described above * @param args flags and optional arguments, as described above.
* @return a CallSite, which, when invoked, will return an instance of the * @return a CallSite, which, when invoked, will return an instance of the
* functional interface * functional interface
* @throws ReflectiveOperationException if the caller is not able to * @throws ReflectiveOperationException if the caller is not able to
......
...@@ -32,9 +32,26 @@ import java.security.PrivilegedExceptionAction; ...@@ -32,9 +32,26 @@ import java.security.PrivilegedExceptionAction;
import java.util.Objects; import java.util.Objects;
/** /**
* Serialized form of a lambda expression. The properties of this class represent the information that is present * Serialized form of a lambda expression. The properties of this class
* at the lambda factory site, including the identity of the primary functional interface method, the identity of the * represent the information that is present at the lambda factory site, including
* implementation method, and any variables captured from the local environment at the time of lambda capture. * static metafactory arguments such as the identity of the primary functional
* interface method and the identity of the implementation method, as well as
* dynamic metafactory arguments such as values captured from the lexical scope
* at the time of lambda capture.
*
* <p>Implementors of serializable lambdas, such as compilers or language
* runtime libraries, are expected to ensure that instances deserialize properly.
* One means to do so is to ensure that the {@code writeReplace} method returns
* an instance of {@code SerializedLambda}, rather than allowing default
* serialization to proceed.
*
* <p>{@code SerializedLambda} has a {@code readResolve} method that looks for
* a (possibly private) static method called
* {@code $deserializeLambda$(SerializedLambda)} in the capturing class, invokes
* that with itself as the first argument, and returns the result. Lambda classes
* implementing {@code $deserializeLambda$} are responsible for validating
* that the properties of the {@code SerializedLambda} are consistent with a
* lambda actually captured by that class.
* *
* @see LambdaMetafactory * @see LambdaMetafactory
*/ */
......
...@@ -127,7 +127,7 @@ public class DoubleSummaryStatistics implements DoubleConsumer { ...@@ -127,7 +127,7 @@ public class DoubleSummaryStatistics implements DoubleConsumer {
* numerical sum compared to a simple summation of {@code double} * numerical sum compared to a simple summation of {@code double}
* values. * values.
* *
* @apiNote Sorting values by increasing absolute magnitude tends to yield * @apiNote Values sorted by increasing absolute magnitude tend to yield
* more accurate results. * more accurate results.
* *
* @return the sum of values, or zero if none * @return the sum of values, or zero if none
......
...@@ -94,10 +94,10 @@ public interface Iterator<E> { ...@@ -94,10 +94,10 @@ public interface Iterator<E> {
} }
/** /**
* Performs the given action for each remaining element, in the order * Performs the given action for each remaining element until all elements
* elements occur when iterating, until all elements have been processed or * have been processed or the action throws an exception. Actions are
* the action throws an exception. Errors or runtime exceptions thrown by * performed in the order of iteration, if that order is specified.
* the action are relayed to the caller. * Exceptions thrown by the action are relayed to the caller.
* *
* @implSpec * @implSpec
* <p>The default implementation behaves as if: * <p>The default implementation behaves as if:
......
...@@ -192,8 +192,9 @@ public interface List<E> extends Collection<E> { ...@@ -192,8 +192,9 @@ public interface List<E> extends Collection<E> {
* The following code can be used to dump the list into a newly * The following code can be used to dump the list into a newly
* allocated array of <tt>String</tt>: * allocated array of <tt>String</tt>:
* *
* <pre> * <pre>{@code
* String[] y = x.toArray(new String[0]);</pre> * String[] y = x.toArray(new String[0]);
* }</pre>
* *
* Note that <tt>toArray(new Object[0])</tt> is identical in function to * Note that <tt>toArray(new Object[0])</tt> is identical in function to
* <tt>toArray()</tt>. * <tt>toArray()</tt>.
...@@ -383,14 +384,13 @@ public interface List<E> extends Collection<E> { ...@@ -383,14 +384,13 @@ public interface List<E> extends Collection<E> {
* *
* @implSpec * @implSpec
* The default implementation is equivalent to, for this {@code list}: * The default implementation is equivalent to, for this {@code list}:
* <pre> * <pre>{@code
* {@code * final ListIterator<E> li = list.listIterator();
* final ListIterator<E> li = list.listIterator(); * while (li.hasNext()) {
* while (li.hasNext()) { * li.set(operator.apply(li.next()));
* li.set(operator.apply(li.next())); * }
* } * }</pre>
* } *
* </pre>
* If the list's list-iterator does not support the {@code set} operation * If the list's list-iterator does not support the {@code set} operation
* then an {@code UnsupportedOperationException} will be thrown when * then an {@code UnsupportedOperationException} will be thrown when
* replacing the first element. * replacing the first element.
...@@ -469,11 +469,11 @@ public interface List<E> extends Collection<E> { ...@@ -469,11 +469,11 @@ public interface List<E> extends Collection<E> {
/** /**
* Returns the hash code value for this list. The hash code of a list * Returns the hash code value for this list. The hash code of a list
* is defined to be the result of the following calculation: * is defined to be the result of the following calculation:
* <pre> * <pre>{@code
* int hashCode = 1; * int hashCode = 1;
* for (E e : list) * for (E e : list)
* hashCode = 31*hashCode + (e==null ? 0 : e.hashCode()); * hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
* </pre> * }</pre>
* This ensures that <tt>list1.equals(list2)</tt> implies that * This ensures that <tt>list1.equals(list2)</tt> implies that
* <tt>list1.hashCode()==list2.hashCode()</tt> for any two lists, * <tt>list1.hashCode()==list2.hashCode()</tt> for any two lists,
* <tt>list1</tt> and <tt>list2</tt>, as required by the general * <tt>list1</tt> and <tt>list2</tt>, as required by the general
...@@ -640,9 +640,9 @@ public interface List<E> extends Collection<E> { ...@@ -640,9 +640,9 @@ public interface List<E> extends Collection<E> {
* a list can be used as a range operation by passing a subList view * a list can be used as a range operation by passing a subList view
* instead of a whole list. For example, the following idiom * instead of a whole list. For example, the following idiom
* removes a range of elements from a list: * removes a range of elements from a list:
* <pre> * <pre>{@code
* list.subList(from, to).clear(); * list.subList(from, to).clear();
* </pre> * }</pre>
* Similar idioms may be constructed for <tt>indexOf</tt> and * Similar idioms may be constructed for <tt>indexOf</tt> and
* <tt>lastIndexOf</tt>, and all of the algorithms in the * <tt>lastIndexOf</tt>, and all of the algorithms in the
* <tt>Collections</tt> class can be applied to a subList.<p> * <tt>Collections</tt> class can be applied to a subList.<p>
......
...@@ -562,9 +562,8 @@ public interface Map<K,V> { ...@@ -562,9 +562,8 @@ public interface Map<K,V> {
// Defaultable methods // Defaultable methods
/** /**
* Returns the value to which the specified key is mapped, * Returns the value to which the specified key is mapped, or
* or {@code defaultValue} if this map contains no mapping * {@code defaultValue} if this map contains no mapping for the key.
* for the key.
* *
* <p>The default implementation makes no guarantees about synchronization * <p>The default implementation makes no guarantees about synchronization
* or atomicity properties of this method. Any implementation providing * or atomicity properties of this method. Any implementation providing
...@@ -591,9 +590,10 @@ public interface Map<K,V> { ...@@ -591,9 +590,10 @@ public interface Map<K,V> {
} }
/** /**
* Performs the given action on each entry in this map, in the order entries * Performs the given action for each entry in this map until all entries
* are returned by an entry set iterator (which may be unspecified), until * have been processed or the action throws an exception. Unless
* all entries have been processed or the action throws an {@code Exception}. * otherwise specified by the implementing class, actions are performed in
* the order of entry set iteration (if an iteration order is specified.)
* Exceptions thrown by the action are relayed to the caller. * Exceptions thrown by the action are relayed to the caller.
* *
* <p>The default implementation should be overridden by implementations if * <p>The default implementation should be overridden by implementations if
...@@ -636,9 +636,9 @@ public interface Map<K,V> { ...@@ -636,9 +636,9 @@ public interface Map<K,V> {
/** /**
* Replaces each entry's value with the result of invoking the given * Replaces each entry's value with the result of invoking the given
* function on that entry, in the order entries are returned by an entry * function on that entry until all entries have been processed or the
* set iterator, until all entries have been processed or the function * function throws an exception. Exceptions thrown by the function are
* throws an exception. * relayed to the caller.
* *
* <p>The default implementation makes no guarantees about synchronization * <p>The default implementation makes no guarantees about synchronization
* or atomicity properties of this method. Any implementation providing * or atomicity properties of this method. Any implementation providing
......
...@@ -76,6 +76,7 @@ public interface PrimitiveIterator<T, T_CONS> extends Iterator<T> { ...@@ -76,6 +76,7 @@ public interface PrimitiveIterator<T, T_CONS> extends Iterator<T> {
* @param action The action to be performed for each element * @param action The action to be performed for each element
* @throws NullPointerException if the specified action is null * @throws NullPointerException if the specified action is null
*/ */
@SuppressWarnings("overloads")
void forEachRemaining(T_CONS action); void forEachRemaining(T_CONS action);
/** /**
...@@ -93,10 +94,10 @@ public interface PrimitiveIterator<T, T_CONS> extends Iterator<T> { ...@@ -93,10 +94,10 @@ public interface PrimitiveIterator<T, T_CONS> extends Iterator<T> {
int nextInt(); int nextInt();
/** /**
* Performs the given action for each remaining element, in the order * Performs the given action for each remaining element until all elements
* elements occur when iterating, until all elements have been processed * have been processed or the action throws an exception. Actions are
* or the action throws an exception. Errors or runtime exceptions * performed in the order of iteration, if that order is specified.
* thrown by the action are relayed to the caller. * Exceptions thrown by the action are relayed to the caller.
* *
* @implSpec * @implSpec
* <p>The default implementation behaves as if: * <p>The default implementation behaves as if:
...@@ -167,10 +168,10 @@ public interface PrimitiveIterator<T, T_CONS> extends Iterator<T> { ...@@ -167,10 +168,10 @@ public interface PrimitiveIterator<T, T_CONS> extends Iterator<T> {
long nextLong(); long nextLong();
/** /**
* Performs the given action for each remaining element, in the order * Performs the given action for each remaining element until all elements
* elements occur when iterating, until all elements have been processed * have been processed or the action throws an exception. Actions are
* or the action throws an exception. Errors or runtime exceptions * performed in the order of iteration, if that order is specified.
* thrown by the action are relayed to the caller. * Exceptions thrown by the action are relayed to the caller.
* *
* @implSpec * @implSpec
* <p>The default implementation behaves as if: * <p>The default implementation behaves as if:
...@@ -240,10 +241,10 @@ public interface PrimitiveIterator<T, T_CONS> extends Iterator<T> { ...@@ -240,10 +241,10 @@ public interface PrimitiveIterator<T, T_CONS> extends Iterator<T> {
double nextDouble(); double nextDouble();
/** /**
* Performs the given action for each remaining element, in the order * Performs the given action for each remaining element until all elements
* elements occur when iterating, until all elements have been processed * have been processed or the action throws an exception. Actions are
* or the action throws an exception. Errors or runtime exceptions * performed in the order of iteration, if that order is specified.
* thrown by the action are relayed to the caller. * Exceptions thrown by the action are relayed to the caller.
* *
* @implSpec * @implSpec
* <p>The default implementation behaves as if: * <p>The default implementation behaves as if:
......
...@@ -613,6 +613,7 @@ public interface Spliterator<T> { ...@@ -613,6 +613,7 @@ public interface Spliterator<T> {
* upon entry to this method, else {@code true}. * upon entry to this method, else {@code true}.
* @throws NullPointerException if the specified action is null * @throws NullPointerException if the specified action is null
*/ */
@SuppressWarnings("overloads")
boolean tryAdvance(T_CONS action); boolean tryAdvance(T_CONS action);
/** /**
...@@ -630,6 +631,7 @@ public interface Spliterator<T> { ...@@ -630,6 +631,7 @@ public interface Spliterator<T> {
* @param action The action * @param action The action
* @throws NullPointerException if the specified action is null * @throws NullPointerException if the specified action is null
*/ */
@SuppressWarnings("overloads")
default void forEachRemaining(T_CONS action) { default void forEachRemaining(T_CONS action) {
do { } while (tryAdvance(action)); do { } while (tryAdvance(action));
} }
......
...@@ -60,7 +60,11 @@ ...@@ -60,7 +60,11 @@
* actions, or predicates. In documenting functional interfaces, or referring * actions, or predicates. In documenting functional interfaces, or referring
* to variables typed as functional interfaces, it is common to refer directly * to variables typed as functional interfaces, it is common to refer directly
* to those abstract concepts, for example using "this function" instead of * to those abstract concepts, for example using "this function" instead of
* "the function represented by this object". * "the function represented by this object". When an API method is said to
* accept or return a functional interface in this manner, such as "applies the
* provided function to...", this is understood to mean a <i>non-null</i>
* reference to an object implementing the appropriate functional interface,
* unless potential nullity is explicitly specified.
* *
* <p>The functional interfaces in this package follow an extensible naming * <p>The functional interfaces in this package follow an extensible naming
* convention, as follows: * convention, as follows:
......
...@@ -35,9 +35,10 @@ import java.util.function.IntConsumer; ...@@ -35,9 +35,10 @@ import java.util.function.IntConsumer;
import java.util.function.Predicate; import java.util.function.Predicate;
/** /**
* A sequence of elements supporting sequential and parallel aggregate * Base interface for streams, which are sequences of elements supporting
* operations. The following example illustrates an aggregate operation using * sequential and parallel aggregate operations. The following example
* {@link Stream} and {@link IntStream}: * illustrates an aggregate operation using the stream types {@link Stream}
* and {@link IntStream}, computing the sum of the weights of the red widgets:
* *
* <pre>{@code * <pre>{@code
* int sum = widgets.stream() * int sum = widgets.stream()
...@@ -46,80 +47,18 @@ import java.util.function.Predicate; ...@@ -46,80 +47,18 @@ import java.util.function.Predicate;
* .sum(); * .sum();
* }</pre> * }</pre>
* *
* In this example, {@code widgets} is a {@code Collection<Widget>}. We create * See the class documentation for {@link Stream} and the package documentation
* a stream of {@code Widget} objects via {@link Collection#stream Collection.stream()}, * for <a href="package-summary.html">java.util.stream</a> for additional
* filter it to produce a stream containing only the red widgets, and then * specification of streams, stream operations, stream pipelines, and
* transform it into a stream of {@code int} values representing the weight of * parallelism, which governs the behavior of all stream types.
* 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 <T> the type of the stream elements
* @param <S> the type of of the stream implementing {@code BaseStream} * @param <S> the type of of the stream implementing {@code BaseStream}
* @since 1.8 * @since 1.8
* @see Stream
* @see IntStream
* @see LongStream
* @see DoubleStream
* @see <a href="package-summary.html">java.util.stream</a> * @see <a href="package-summary.html">java.util.stream</a>
*/ */
public interface BaseStream<T, S extends BaseStream<T, S>> public interface BaseStream<T, S extends BaseStream<T, S>>
......
...@@ -462,7 +462,7 @@ public final class Collectors { ...@@ -462,7 +462,7 @@ public final class Collectors {
*/ */
public static <T> Collector<T, ?, Integer> public static <T> Collector<T, ?, Integer>
summingInt(ToIntFunction<? super T> mapper) { summingInt(ToIntFunction<? super T> mapper) {
return new CollectorImpl<T, int[], Integer>( return new CollectorImpl<>(
() -> new int[1], () -> new int[1],
(a, t) -> { a[0] += mapper.applyAsInt(t); }, (a, t) -> { a[0] += mapper.applyAsInt(t); },
(a, b) -> { a[0] += b[0]; return a; }, (a, b) -> { a[0] += b[0]; return a; },
...@@ -480,7 +480,7 @@ public final class Collectors { ...@@ -480,7 +480,7 @@ public final class Collectors {
*/ */
public static <T> Collector<T, ?, Long> public static <T> Collector<T, ?, Long>
summingLong(ToLongFunction<? super T> mapper) { summingLong(ToLongFunction<? super T> mapper) {
return new CollectorImpl<T, long[], Long>( return new CollectorImpl<>(
() -> new long[1], () -> new long[1],
(a, t) -> { a[0] += mapper.applyAsLong(t); }, (a, t) -> { a[0] += mapper.applyAsLong(t); },
(a, b) -> { a[0] += b[0]; return a; }, (a, b) -> { a[0] += b[0]; return a; },
...@@ -505,7 +505,7 @@ public final class Collectors { ...@@ -505,7 +505,7 @@ public final class Collectors {
*/ */
public static <T> Collector<T, ?, Double> public static <T> Collector<T, ?, Double>
summingDouble(ToDoubleFunction<? super T> mapper) { summingDouble(ToDoubleFunction<? super T> mapper) {
return new CollectorImpl<T, double[], Double>( return new CollectorImpl<>(
() -> new double[1], () -> new double[1],
(a, t) -> { a[0] += mapper.applyAsDouble(t); }, (a, t) -> { a[0] += mapper.applyAsDouble(t); },
(a, b) -> { a[0] += b[0]; return a; }, (a, b) -> { a[0] += b[0]; return a; },
...@@ -523,7 +523,7 @@ public final class Collectors { ...@@ -523,7 +523,7 @@ public final class Collectors {
*/ */
public static <T> Collector<T, ?, Double> public static <T> Collector<T, ?, Double>
averagingInt(ToIntFunction<? super T> mapper) { averagingInt(ToIntFunction<? super T> mapper) {
return new CollectorImpl<T, long[], Double>( return new CollectorImpl<>(
() -> new long[2], () -> new long[2],
(a, t) -> { a[0] += mapper.applyAsInt(t); a[1]++; }, (a, t) -> { a[0] += mapper.applyAsInt(t); a[1]++; },
(a, b) -> { a[0] += b[0]; a[1] += b[1]; return a; }, (a, b) -> { a[0] += b[0]; a[1] += b[1]; return a; },
...@@ -541,7 +541,7 @@ public final class Collectors { ...@@ -541,7 +541,7 @@ public final class Collectors {
*/ */
public static <T> Collector<T, ?, Double> public static <T> Collector<T, ?, Double>
averagingLong(ToLongFunction<? super T> mapper) { averagingLong(ToLongFunction<? super T> mapper) {
return new CollectorImpl<T, long[], Double>( return new CollectorImpl<>(
() -> new long[2], () -> new long[2],
(a, t) -> { a[0] += mapper.applyAsLong(t); a[1]++; }, (a, t) -> { a[0] += mapper.applyAsLong(t); a[1]++; },
(a, b) -> { a[0] += b[0]; a[1] += b[1]; return a; }, (a, b) -> { a[0] += b[0]; a[1] += b[1]; return a; },
...@@ -566,7 +566,7 @@ public final class Collectors { ...@@ -566,7 +566,7 @@ public final class Collectors {
*/ */
public static <T> Collector<T, ?, Double> public static <T> Collector<T, ?, Double>
averagingDouble(ToDoubleFunction<? super T> mapper) { averagingDouble(ToDoubleFunction<? super T> mapper) {
return new CollectorImpl<T, double[], Double>( return new CollectorImpl<>(
() -> new double[2], () -> new double[2],
(a, t) -> { a[0] += mapper.applyAsDouble(t); a[1]++; }, (a, t) -> { a[0] += mapper.applyAsDouble(t); a[1]++; },
(a, b) -> { a[0] += b[0]; a[1] += b[1]; return a; }, (a, b) -> { a[0] += b[0]; a[1] += b[1]; return a; },
...@@ -723,6 +723,14 @@ public final class Collectors { ...@@ -723,6 +723,14 @@ public final class Collectors {
* groupingBy(classifier, toList()); * groupingBy(classifier, toList());
* }</pre> * }</pre>
* *
* @implNote
* The returned {@code Collector} is not concurrent. For parallel stream
* pipelines, the {@code combiner} function operates by merging the keys
* from one map into another, which can be an expensive operation. If
* preservation of the order in which elements appear in the resulting {@code Map}
* collector is not required, using {@link #groupingByConcurrent(Function)}
* may offer better parallel performance.
*
* @param <T> the type of the input elements * @param <T> the type of the input elements
* @param <K> the type of the keys * @param <K> the type of the keys
* @param classifier the classifier function mapping input elements to keys * @param classifier the classifier function mapping input elements to keys
...@@ -759,6 +767,14 @@ public final class Collectors { ...@@ -759,6 +767,14 @@ public final class Collectors {
* mapping(Person::getLastName, toSet()))); * mapping(Person::getLastName, toSet())));
* }</pre> * }</pre>
* *
* @implNote
* The returned {@code Collector} is not concurrent. For parallel stream
* pipelines, the {@code combiner} function operates by merging the keys
* from one map into another, which can be an expensive operation. If
* preservation of the order in which elements are presented to the downstream
* collector is not required, using {@link #groupingByConcurrent(Function, Collector)}
* may offer better parallel performance.
*
* @param <T> the type of the input elements * @param <T> the type of the input elements
* @param <K> the type of the keys * @param <K> the type of the keys
* @param <A> the intermediate accumulation type of the downstream collector * @param <A> the intermediate accumulation type of the downstream collector
...@@ -798,6 +814,14 @@ public final class Collectors { ...@@ -798,6 +814,14 @@ public final class Collectors {
* mapping(Person::getLastName, toSet()))); * mapping(Person::getLastName, toSet())));
* }</pre> * }</pre>
* *
* @implNote
* The returned {@code Collector} is not concurrent. For parallel stream
* pipelines, the {@code combiner} function operates by merging the keys
* from one map into another, which can be an expensive operation. If
* preservation of the order in which elements are presented to the downstream
* collector is not required, using {@link #groupingByConcurrent(Function, Supplier, Collector)}
* may offer better parallel performance.
*
* @param <T> the type of the input elements * @param <T> the type of the input elements
* @param <K> the type of the keys * @param <K> the type of the keys
* @param <A> the intermediate accumulation type of the downstream collector * @param <A> the intermediate accumulation type of the downstream collector
...@@ -871,7 +895,7 @@ public final class Collectors { ...@@ -871,7 +895,7 @@ public final class Collectors {
* @param <T> the type of the input elements * @param <T> the type of the input elements
* @param <K> the type of the keys * @param <K> the type of the keys
* @param classifier a classifier function mapping input elements to keys * @param classifier a classifier function mapping input elements to keys
* @return a {@code Collector} implementing the group-by operation * @return a concurrent, unordered {@code Collector} implementing the group-by operation
* *
* @see #groupingBy(Function) * @see #groupingBy(Function)
* @see #groupingByConcurrent(Function, Collector) * @see #groupingByConcurrent(Function, Collector)
...@@ -912,7 +936,7 @@ public final class Collectors { ...@@ -912,7 +936,7 @@ public final class Collectors {
* @param <D> the result type of the downstream reduction * @param <D> the result type of the downstream reduction
* @param classifier a classifier function mapping input elements to keys * @param classifier a classifier function mapping input elements to keys
* @param downstream a {@code Collector} implementing the downstream reduction * @param downstream a {@code Collector} implementing the downstream reduction
* @return a {@code Collector} implementing the cascaded group-by operation * @return a concurrent, unordered {@code Collector} implementing the cascaded group-by operation
* *
* @see #groupingBy(Function, Collector) * @see #groupingBy(Function, Collector)
* @see #groupingByConcurrent(Function) * @see #groupingByConcurrent(Function)
...@@ -958,7 +982,7 @@ public final class Collectors { ...@@ -958,7 +982,7 @@ public final class Collectors {
* @param downstream a {@code Collector} implementing the downstream reduction * @param downstream a {@code Collector} implementing the downstream reduction
* @param mapFactory a function which, when called, produces a new empty * @param mapFactory a function which, when called, produces a new empty
* {@code ConcurrentMap} of the desired type * {@code ConcurrentMap} of the desired type
* @return a {@code Collector} implementing the cascaded group-by operation * @return a concurrent, unordered {@code Collector} implementing the cascaded group-by operation
* *
* @see #groupingByConcurrent(Function) * @see #groupingByConcurrent(Function)
* @see #groupingByConcurrent(Function, Collector) * @see #groupingByConcurrent(Function, Collector)
...@@ -1072,7 +1096,7 @@ public final class Collectors { ...@@ -1072,7 +1096,7 @@ public final class Collectors {
} }
/** /**
* Returns a {@code Collector} that accumulate elements into a * Returns a {@code Collector} that accumulates elements into a
* {@code Map} whose keys and values are the result of applying the provided * {@code Map} whose keys and values are the result of applying the provided
* mapping functions to the input elements. * mapping functions to the input elements.
* *
...@@ -1101,6 +1125,14 @@ public final class Collectors { ...@@ -1101,6 +1125,14 @@ public final class Collectors {
* Functions.identity()); * Functions.identity());
* }</pre> * }</pre>
* *
* @implNote
* The returned {@code Collector} is not concurrent. For parallel stream
* pipelines, the {@code combiner} function operates by merging the keys
* from one map into another, which can be an expensive operation. If it is
* not required that results are inserted into the {@code Map} in encounter
* order, using {@link #toConcurrentMap(Function, Function)}
* may offer better parallel performance.
*
* @param <T> the type of the input elements * @param <T> the type of the input elements
* @param <K> the output type of the key mapping function * @param <K> the output type of the key mapping function
* @param <U> the output type of the value mapping function * @param <U> the output type of the value mapping function
...@@ -1121,7 +1153,7 @@ public final class Collectors { ...@@ -1121,7 +1153,7 @@ public final class Collectors {
} }
/** /**
* Returns a {@code Collector} that accumulate elements into a * Returns a {@code Collector} that accumulates elements into a
* {@code Map} whose keys and values are the result of applying the provided * {@code Map} whose keys and values are the result of applying the provided
* mapping functions to the input elements. * mapping functions to the input elements.
* *
...@@ -1146,6 +1178,14 @@ public final class Collectors { ...@@ -1146,6 +1178,14 @@ public final class Collectors {
* (s, a) -> s + ", " + a)); * (s, a) -> s + ", " + a));
* }</pre> * }</pre>
* *
* @implNote
* The returned {@code Collector} is not concurrent. For parallel stream
* pipelines, the {@code combiner} function operates by merging the keys
* from one map into another, which can be an expensive operation. If it is
* not required that results are merged into the {@code Map} in encounter
* order, using {@link #toConcurrentMap(Function, Function, BinaryOperator)}
* may offer better parallel performance.
*
* @param <T> the type of the input elements * @param <T> the type of the input elements
* @param <K> the output type of the key mapping function * @param <K> the output type of the key mapping function
* @param <U> the output type of the value mapping function * @param <U> the output type of the value mapping function
...@@ -1172,7 +1212,7 @@ public final class Collectors { ...@@ -1172,7 +1212,7 @@ public final class Collectors {
} }
/** /**
* Returns a {@code Collector} that accumulate elements into a * Returns a {@code Collector} that accumulates elements into a
* {@code Map} whose keys and values are the result of applying the provided * {@code Map} whose keys and values are the result of applying the provided
* mapping functions to the input elements. * mapping functions to the input elements.
* *
...@@ -1182,6 +1222,14 @@ public final class Collectors { ...@@ -1182,6 +1222,14 @@ public final class Collectors {
* results are merged using the provided merging function. The {@code Map} * results are merged using the provided merging function. The {@code Map}
* is created by a provided supplier function. * is created by a provided supplier function.
* *
* @implNote
* The returned {@code Collector} is not concurrent. For parallel stream
* pipelines, the {@code combiner} function operates by merging the keys
* from one map into another, which can be an expensive operation. If it is
* not required that results are merged into the {@code Map} in encounter
* order, using {@link #toConcurrentMap(Function, Function, BinaryOperator, Supplier)}
* may offer better parallel performance.
*
* @param <T> the type of the input elements * @param <T> the type of the input elements
* @param <K> the output type of the key mapping function * @param <K> the output type of the key mapping function
* @param <U> the output type of the value mapping function * @param <U> the output type of the value mapping function
...@@ -1215,7 +1263,7 @@ public final class Collectors { ...@@ -1215,7 +1263,7 @@ public final class Collectors {
} }
/** /**
* Returns a {@code Collector} that accumulate elements into a * Returns a concurrent {@code Collector} that accumulates elements into a
* {@code ConcurrentMap} whose keys and values are the result of applying * {@code ConcurrentMap} whose keys and values are the result of applying
* the provided mapping functions to the input elements. * the provided mapping functions to the input elements.
* *
...@@ -1252,7 +1300,7 @@ public final class Collectors { ...@@ -1252,7 +1300,7 @@ public final class Collectors {
* @param <U> the output type of the value mapping function * @param <U> the output type of the value mapping function
* @param keyMapper the mapping function to produce keys * @param keyMapper the mapping function to produce keys
* @param valueMapper the mapping function to produce values * @param valueMapper the mapping function to produce values
* @return a concurrent {@code Collector} which collects elements into a * @return a concurrent, unordered {@code Collector} which collects elements into a
* {@code ConcurrentMap} whose keys are the result of applying a key mapping * {@code ConcurrentMap} whose keys are the result of applying a key mapping
* function to the input elements, and whose values are the result of * function to the input elements, and whose values are the result of
* applying a value mapping function to the input elements * applying a value mapping function to the input elements
...@@ -1268,7 +1316,7 @@ public final class Collectors { ...@@ -1268,7 +1316,7 @@ public final class Collectors {
} }
/** /**
* Returns a {@code Collector} that accumulate elements into a * Returns a concurrent {@code Collector} that accumulates elements into a
* {@code ConcurrentMap} whose keys and values are the result of applying * {@code ConcurrentMap} whose keys and values are the result of applying
* the provided mapping functions to the input elements. * the provided mapping functions to the input elements.
* *
...@@ -1303,7 +1351,7 @@ public final class Collectors { ...@@ -1303,7 +1351,7 @@ public final class Collectors {
* @param mergeFunction a merge function, used to resolve collisions between * @param mergeFunction a merge function, used to resolve collisions between
* values associated with the same key, as supplied * values associated with the same key, as supplied
* to {@link Map#merge(Object, Object, BiFunction)} * to {@link Map#merge(Object, Object, BiFunction)}
* @return a concurrent {@code Collector} which collects elements into a * @return a concurrent, unordered {@code Collector} which collects elements into a
* {@code ConcurrentMap} whose keys are the result of applying a key mapping * {@code ConcurrentMap} whose keys are the result of applying a key mapping
* function to the input elements, and whose values are the result of * function to the input elements, and whose values are the result of
* applying a value mapping function to all input elements equal to the key * applying a value mapping function to all input elements equal to the key
...@@ -1322,7 +1370,7 @@ public final class Collectors { ...@@ -1322,7 +1370,7 @@ public final class Collectors {
} }
/** /**
* Returns a {@code Collector} that accumulate elements into a * Returns a concurrent {@code Collector} that accumulates elements into a
* {@code ConcurrentMap} whose keys and values are the result of applying * {@code ConcurrentMap} whose keys and values are the result of applying
* the provided mapping functions to the input elements. * the provided mapping functions to the input elements.
* *
...@@ -1345,7 +1393,7 @@ public final class Collectors { ...@@ -1345,7 +1393,7 @@ public final class Collectors {
* to {@link Map#merge(Object, Object, BiFunction)} * to {@link Map#merge(Object, Object, BiFunction)}
* @param mapSupplier a function which returns a new, empty {@code Map} into * @param mapSupplier a function which returns a new, empty {@code Map} into
* which the results will be inserted * which the results will be inserted
* @return a concurrent {@code Collector} which collects elements into a * @return a concurrent, unordered {@code Collector} which collects elements into a
* {@code ConcurrentMap} whose keys are the result of applying a key mapping * {@code ConcurrentMap} whose keys are the result of applying a key mapping
* function to the input elements, and whose values are the result of * function to the input elements, and whose values are the result of
* applying a value mapping function to all input elements equal to the key * applying a value mapping function to all input elements equal to the key
......
...@@ -50,9 +50,13 @@ import java.util.function.ObjDoubleConsumer; ...@@ -50,9 +50,13 @@ import java.util.function.ObjDoubleConsumer;
import java.util.function.Supplier; import java.util.function.Supplier;
/** /**
* A sequence of elements supporting sequential and parallel aggregate * A sequence of primitive double-valued elements supporting sequential and parallel
* operations. The following example illustrates an aggregate operation using * aggregate operations. This is the {@code double} primitive specialization of
* {@link Stream} and {@link DoubleStream}: * {@link Stream}.
*
* <p>The following example illustrates an aggregate operation using
* {@link Stream} and {@link DoubleStream}, computing the sum of the weights of the
* red widgets:
* *
* <pre>{@code * <pre>{@code
* double sum = widgets.stream() * double sum = widgets.stream()
...@@ -61,78 +65,13 @@ import java.util.function.Supplier; ...@@ -61,78 +65,13 @@ import java.util.function.Supplier;
* .sum(); * .sum();
* }</pre> * }</pre>
* *
* In this example, {@code widgets} is a {@code Collection<Widget>}. We create * See the class documentation for {@link Stream} and the package documentation
* a stream of {@code Widget} objects via {@link Collection#stream Collection.stream()}, * for <a href="package-summary.html">java.util.stream</a> for additional
* filter it to produce a stream containing only the red widgets, and then * specification of streams, stream operations, stream pipelines, and
* transform it into a stream of {@code double} values representing the weight of * parallelism.
* 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 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.
*
* <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 * @since 1.8
* @see Stream
* @see <a href="package-summary.html">java.util.stream</a> * @see <a href="package-summary.html">java.util.stream</a>
*/ */
public interface DoubleStream extends BaseStream<Double, DoubleStream> { public interface DoubleStream extends BaseStream<Double, DoubleStream> {
...@@ -144,9 +83,10 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> { ...@@ -144,9 +83,10 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
* <p>This is an <a href="package-summary.html#StreamOps">intermediate * <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>. * operation</a>.
* *
* @param predicate a <a href="package-summary.html#NonInterference"> * @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>,
* non-interfering, stateless</a> predicate to apply to * <a href="package-summary.html#Statelessness">stateless</a>
* each element to determine if it should be included * predicate to apply to each element to determine if it
* should be included
* @return the new stream * @return the new stream
*/ */
DoubleStream filter(DoublePredicate predicate); DoubleStream filter(DoublePredicate predicate);
...@@ -158,9 +98,9 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> { ...@@ -158,9 +98,9 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
* <p>This is an <a href="package-summary.html#StreamOps">intermediate * <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>. * operation</a>.
* *
* @param mapper a <a href="package-summary.html#NonInterference"> * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* non-interfering, stateless</a> function to apply to * <a href="package-summary.html#Statelessness">stateless</a>
* each element * function to apply to each element
* @return the new stream * @return the new stream
*/ */
DoubleStream map(DoubleUnaryOperator mapper); DoubleStream map(DoubleUnaryOperator mapper);
...@@ -173,9 +113,9 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> { ...@@ -173,9 +113,9 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
* intermediate operation</a>. * intermediate operation</a>.
* *
* @param <U> the element type of the new stream * @param <U> the element type of the new stream
* @param mapper a <a href="package-summary.html#NonInterference"> * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* non-interfering, stateless</a> function to apply to each * <a href="package-summary.html#Statelessness">stateless</a>
* element * function to apply to each element
* @return the new stream * @return the new stream
*/ */
<U> Stream<U> mapToObj(DoubleFunction<? extends U> mapper); <U> Stream<U> mapToObj(DoubleFunction<? extends U> mapper);
...@@ -187,9 +127,9 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> { ...@@ -187,9 +127,9 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
* <p>This is an <a href="package-summary.html#StreamOps">intermediate * <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>. * operation</a>.
* *
* @param mapper a <a href="package-summary.html#NonInterference"> * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* non-interfering, stateless</a> function to apply to each * <a href="package-summary.html#Statelessness">stateless</a>
* element * function to apply to each element
* @return the new stream * @return the new stream
*/ */
IntStream mapToInt(DoubleToIntFunction mapper); IntStream mapToInt(DoubleToIntFunction mapper);
...@@ -201,9 +141,9 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> { ...@@ -201,9 +141,9 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
* <p>This is an <a href="package-summary.html#StreamOps">intermediate * <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>. * operation</a>.
* *
* @param mapper a <a href="package-summary.html#NonInterference"> * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* non-interfering, stateless</a> function to apply to each * <a href="package-summary.html#Statelessness">stateless</a>
* element * function to apply to each element
* @return the new stream * @return the new stream
*/ */
LongStream mapToLong(DoubleToLongFunction mapper); LongStream mapToLong(DoubleToLongFunction mapper);
...@@ -218,10 +158,10 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> { ...@@ -218,10 +158,10 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
* <p>This is an <a href="package-summary.html#StreamOps">intermediate * <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>. * operation</a>.
* *
* @param mapper a <a href="package-summary.html#NonInterference"> * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* non-interfering, stateless</a> function to apply to * <a href="package-summary.html#Statelessness">stateless</a>
* each element which produces an {@code DoubleStream} of new * function to apply to each element which produces a
* values * {@code DoubleStream} of new values
* @return the new stream * @return the new stream
* @see Stream#flatMap(Function) * @see Stream#flatMap(Function)
*/ */
...@@ -276,8 +216,8 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> { ...@@ -276,8 +216,8 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
* }</pre> * }</pre>
* *
* @param action 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 * non-interfering</a> action to perform on the elements as
* they are consumed from the stream * they are consumed from the stream
* @return the new stream * @return the new stream
*/ */
DoubleStream peek(DoubleConsumer action); DoubleStream peek(DoubleConsumer action);
...@@ -423,9 +363,10 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> { ...@@ -423,9 +363,10 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
* synchronization and with greatly reduced risk of data races. * synchronization and with greatly reduced risk of data races.
* *
* @param identity the identity value for the accumulating function * @param identity the identity value for the accumulating function
* @param op an <a href="package-summary.html#Associativity">associative</a> * @param op an <a href="package-summary.html#Associativity">associative</a>,
* <a href="package-summary.html#NonInterference">non-interfering, * <a href="package-summary.html#NonInterference">non-interfering</a>,
* stateless</a> function for combining two values * <a href="package-summary.html#Statelessness">stateless</a>
* function for combining two values
* @return the result of the reduction * @return the result of the reduction
* @see #sum() * @see #sum()
* @see #min() * @see #min()
...@@ -462,9 +403,10 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> { ...@@ -462,9 +403,10 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
* <p>This is a <a href="package-summary.html#StreamOps">terminal * <p>This is a <a href="package-summary.html#StreamOps">terminal
* operation</a>. * operation</a>.
* *
* @param op an <a href="package-summary.html#Associativity">associative</a> * @param op an <a href="package-summary.html#Associativity">associative</a>,
* <a href="package-summary.html#NonInterference">non-interfering, * <a href="package-summary.html#NonInterference">non-interfering</a>,
* stateless</a> function for combining two values * <a href="package-summary.html#Statelessness">stateless</a>
* function for combining two values
* @return the result of the reduction * @return the result of the reduction
* @see #reduce(double, DoubleBinaryOperator) * @see #reduce(double, DoubleBinaryOperator)
*/ */
...@@ -495,14 +437,15 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> { ...@@ -495,14 +437,15 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
* @param supplier a function that creates a new result container. For a * @param supplier a function that creates a new result container. For a
* parallel execution, this function may be called * parallel execution, this function may be called
* multiple times and must return a fresh value each time. * multiple times and must return a fresh value each time.
* @param accumulator an <a href="package-summary.html#Associativity">associative</a> * @param accumulator an <a href="package-summary.html#Associativity">associative</a>,
* <a href="package-summary.html#NonInterference">non-interfering, * <a href="package-summary.html#NonInterference">non-interfering</a>,
* stateless</a> function for incorporating an additional * <a href="package-summary.html#Statelessness">stateless</a>
* element into a result * function for incorporating an additional element into a result
* @param combiner an <a href="package-summary.html#Associativity">associative</a> * @param combiner an <a href="package-summary.html#Associativity">associative</a>,
* <a href="package-summary.html#NonInterference">non-interfering, * <a href="package-summary.html#NonInterference">non-interfering</a>,
* stateless</a> function for combining two values, which * <a href="package-summary.html#Statelessness">stateless</a>
* must be compatible with the accumulator function * function for combining two values, which must be
* compatible with the accumulator function
* @return the result of the reduction * @return the result of the reduction
* @see Stream#collect(Supplier, BiConsumer, BiConsumer) * @see Stream#collect(Supplier, BiConsumer, BiConsumer)
*/ */
...@@ -544,8 +487,8 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> { ...@@ -544,8 +487,8 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
* <p>This is a <a href="package-summary.html#StreamOps">terminal * <p>This is a <a href="package-summary.html#StreamOps">terminal
* operation</a>. * operation</a>.
* *
* @apiNote Sorting values by increasing absolute magnitude tends to yield * @apiNote Elements sorted by increasing absolute magnitude tend
* more accurate results. * to yield more accurate results.
* *
* @return the sum of elements in this stream * @return the sum of elements in this stream
*/ */
...@@ -651,48 +594,67 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> { ...@@ -651,48 +594,67 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
/** /**
* Returns whether any elements of this stream match the provided * Returns whether any elements of this stream match the provided
* predicate. May not evaluate the predicate on all elements if not * predicate. May not evaluate the predicate on all elements if not
* necessary for determining the result. * necessary for determining the result. If the stream is empty then
* {@code false} is returned and the predicate is not evaluated.
* *
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
* terminal operation</a>. * terminal operation</a>.
* *
* @param predicate a <a href="package-summary.html#NonInterference">non-interfering, * @apiNote
* stateless</a> predicate to apply to elements of this * This method evaluates the <em>existential quantification</em> of the
* stream * predicate over the elements of the stream (for some x P(x)).
*
* @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* predicate to apply to elements of this stream
* @return {@code true} if any elements of the stream match the provided * @return {@code true} if any elements of the stream match the provided
* predicate otherwise {@code false} * predicate, otherwise {@code false}
*/ */
boolean anyMatch(DoublePredicate predicate); boolean anyMatch(DoublePredicate predicate);
/** /**
* Returns whether all elements of this stream match the provided predicate. * Returns whether all elements of this stream match the provided predicate.
* May not evaluate the predicate on all elements if not necessary for * May not evaluate the predicate on all elements if not necessary for
* determining the result. * determining the result. If the stream is empty then {@code true} is
* returned and the predicate is not evaluated.
* *
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
* terminal operation</a>. * terminal operation</a>.
* *
* @param predicate a <a href="package-summary.html#NonInterference">non-interfering, * @apiNote
* stateless</a> predicate to apply to elements of this * This method evaluates the <em>universal quantification</em> of the
* stream * predicate over the elements of the stream (for all x P(x)). If the
* @return {@code true} if all elements of the stream match the provided * stream is empty, the quantification is said to be <em>vacuously
* predicate otherwise {@code false} * satisfied</em> and is always {@code true} (regardless of P(x)).
*
* @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* predicate to apply to elements of this stream
* @return {@code true} if either all elements of the stream match the
* provided predicate or the stream is empty, otherwise {@code false}
*/ */
boolean allMatch(DoublePredicate predicate); boolean allMatch(DoublePredicate predicate);
/** /**
* Returns whether no elements of this stream match the provided predicate. * Returns whether no elements of this stream match the provided predicate.
* May not evaluate the predicate on all elements if not necessary for * May not evaluate the predicate on all elements if not necessary for
* determining the result. * determining the result. If the stream is empty then {@code true} is
* returned and the predicate is not evaluated.
* *
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
* terminal operation</a>. * terminal operation</a>.
* *
* @param predicate a <a href="package-summary.html#NonInterference">non-interfering, * @apiNote
* stateless</a> predicate to apply to elements of this * This method evaluates the <em>universal quantification</em> of the
* stream * negated predicate over the elements of the stream (for all x ~P(x)). If
* @return {@code true} if no elements of the stream match the provided * the stream is empty, the quantification is said to be vacuously satisfied
* predicate otherwise {@code false} * and is always {@code true}, regardless of P(x).
*
* @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* predicate to apply to elements of this stream
* @return {@code true} if either no elements of the stream match the
* provided predicate or the stream is empty, otherwise {@code false}
*/ */
boolean noneMatch(DoublePredicate predicate); boolean noneMatch(DoublePredicate predicate);
...@@ -832,12 +794,12 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> { ...@@ -832,12 +794,12 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
} }
/** /**
* Returns a sequential stream where each element is generated by * Returns an infinite sequential unordered stream where each element is
* the provided {@code DoubleSupplier}. This is suitable for generating * generated by the provided {@code DoubleSupplier}. This is suitable for
* constant streams, streams of random elements, etc. * generating constant streams, streams of random elements, etc.
* *
* @param s the {@code DoubleSupplier} for generated elements * @param s the {@code DoubleSupplier} for generated elements
* @return a new sequential {@code DoubleStream} * @return a new infinite sequential unordered {@code DoubleStream}
*/ */
public static DoubleStream generate(DoubleSupplier s) { public static DoubleStream generate(DoubleSupplier s) {
Objects.requireNonNull(s); Objects.requireNonNull(s);
...@@ -848,11 +810,16 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> { ...@@ -848,11 +810,16 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
/** /**
* Creates a lazily concatenated stream whose elements are all the * Creates a lazily concatenated stream whose elements are all the
* elements of the first stream followed by all the elements of the * elements of the first stream followed by all the elements of the
* second stream. The resulting stream is ordered if both * second stream. The resulting stream is ordered if both
* of the input streams are ordered, and parallel if either of the input * of the input streams are ordered, and parallel if either of the input
* streams is parallel. When the resulting stream is closed, the close * streams is parallel. When the resulting stream is closed, the close
* handlers for both input streams are invoked. * handlers for both input streams are invoked.
* *
* @implNote
* Use caution when constructing streams from repeated concatenation.
* Accessing an element of a deeply concatenated stream can result in deep
* call chains, or even {@code StackOverflowException}.
*
* @param a the first stream * @param a the first stream
* @param b the second stream * @param b the second stream
* @return the concatenation of the two input streams * @return the concatenation of the two input streams
......
...@@ -24,11 +24,7 @@ ...@@ -24,11 +24,7 @@
*/ */
package java.util.stream; 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.Arrays;
import java.util.Collection;
import java.util.IntSummaryStatistics; import java.util.IntSummaryStatistics;
import java.util.Objects; import java.util.Objects;
import java.util.OptionalDouble; import java.util.OptionalDouble;
...@@ -36,7 +32,6 @@ import java.util.OptionalInt; ...@@ -36,7 +32,6 @@ import java.util.OptionalInt;
import java.util.PrimitiveIterator; import java.util.PrimitiveIterator;
import java.util.Spliterator; import java.util.Spliterator;
import java.util.Spliterators; import java.util.Spliterators;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.IntBinaryOperator; import java.util.function.IntBinaryOperator;
...@@ -51,9 +46,13 @@ import java.util.function.ObjIntConsumer; ...@@ -51,9 +46,13 @@ import java.util.function.ObjIntConsumer;
import java.util.function.Supplier; import java.util.function.Supplier;
/** /**
* A sequence of elements supporting sequential and parallel aggregate * A sequence of primitive int-valued elements supporting sequential and parallel
* operations. The following example illustrates an aggregate operation using * aggregate operations. This is the {@code int} primitive specialization of
* {@link Stream} and {@link IntStream}: * {@link Stream}.
*
* <p>The following example illustrates an aggregate operation using
* {@link Stream} and {@link IntStream}, computing the sum of the weights of the
* red widgets:
* *
* <pre>{@code * <pre>{@code
* int sum = widgets.stream() * int sum = widgets.stream()
...@@ -62,78 +61,13 @@ import java.util.function.Supplier; ...@@ -62,78 +61,13 @@ import java.util.function.Supplier;
* .sum(); * .sum();
* }</pre> * }</pre>
* *
* In this example, {@code widgets} is a {@code Collection<Widget>}. We create * See the class documentation for {@link Stream} and the package documentation
* a stream of {@code Widget} objects via {@link Collection#stream Collection.stream()}, * for <a href="package-summary.html">java.util.stream</a> for additional
* filter it to produce a stream containing only the red widgets, and then * specification of streams, stream operations, stream pipelines, and
* transform it into a stream of {@code int} values representing the weight of * parallelism.
* 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 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.
*
* <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 * @since 1.8
* @see Stream
* @see <a href="package-summary.html">java.util.stream</a> * @see <a href="package-summary.html">java.util.stream</a>
*/ */
public interface IntStream extends BaseStream<Integer, IntStream> { public interface IntStream extends BaseStream<Integer, IntStream> {
...@@ -145,9 +79,10 @@ public interface IntStream extends BaseStream<Integer, IntStream> { ...@@ -145,9 +79,10 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
* <p>This is an <a href="package-summary.html#StreamOps">intermediate * <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>. * operation</a>.
* *
* @param predicate a <a href="package-summary.html#NonInterference"> * @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>,
* non-interfering, stateless</a> predicate to apply to * <a href="package-summary.html#Statelessness">stateless</a>
* each element to determine if it should be included * predicate to apply to each element to determine if it
* should be included
* @return the new stream * @return the new stream
*/ */
IntStream filter(IntPredicate predicate); IntStream filter(IntPredicate predicate);
...@@ -159,9 +94,9 @@ public interface IntStream extends BaseStream<Integer, IntStream> { ...@@ -159,9 +94,9 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
* <p>This is an <a href="package-summary.html#StreamOps">intermediate * <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>. * operation</a>.
* *
* @param mapper a <a href="package-summary.html#NonInterference"> * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* non-interfering, stateless</a> function to apply to each * <a href="package-summary.html#Statelessness">stateless</a>
* element * function to apply to each element
* @return the new stream * @return the new stream
*/ */
IntStream map(IntUnaryOperator mapper); IntStream map(IntUnaryOperator mapper);
...@@ -174,9 +109,9 @@ public interface IntStream extends BaseStream<Integer, IntStream> { ...@@ -174,9 +109,9 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
* intermediate operation</a>. * intermediate operation</a>.
* *
* @param <U> the element type of the new stream * @param <U> the element type of the new stream
* @param mapper a <a href="package-summary.html#NonInterference"> * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* non-interfering, stateless</a> function to apply to each * <a href="package-summary.html#Statelessness">stateless</a>
* element * function to apply to each element
* @return the new stream * @return the new stream
*/ */
<U> Stream<U> mapToObj(IntFunction<? extends U> mapper); <U> Stream<U> mapToObj(IntFunction<? extends U> mapper);
...@@ -188,9 +123,9 @@ public interface IntStream extends BaseStream<Integer, IntStream> { ...@@ -188,9 +123,9 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
* <p>This is an <a href="package-summary.html#StreamOps">intermediate * <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>. * operation</a>.
* *
* @param mapper a <a href="package-summary.html#NonInterference"> * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* non-interfering, stateless</a> function to apply to each * <a href="package-summary.html#Statelessness">stateless</a>
* element * function to apply to each element
* @return the new stream * @return the new stream
*/ */
LongStream mapToLong(IntToLongFunction mapper); LongStream mapToLong(IntToLongFunction mapper);
...@@ -202,9 +137,9 @@ public interface IntStream extends BaseStream<Integer, IntStream> { ...@@ -202,9 +137,9 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
* <p>This is an <a href="package-summary.html#StreamOps">intermediate * <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>. * operation</a>.
* *
* @param mapper a <a href="package-summary.html#NonInterference"> * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* non-interfering, stateless</a> function to apply to each * <a href="package-summary.html#Statelessness">stateless</a>
* element * function to apply to each element
* @return the new stream * @return the new stream
*/ */
DoubleStream mapToDouble(IntToDoubleFunction mapper); DoubleStream mapToDouble(IntToDoubleFunction mapper);
...@@ -219,10 +154,10 @@ public interface IntStream extends BaseStream<Integer, IntStream> { ...@@ -219,10 +154,10 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
* <p>This is an <a href="package-summary.html#StreamOps">intermediate * <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>. * operation</a>.
* *
* @param mapper a <a href="package-summary.html#NonInterference"> * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* non-interfering, stateless</a> function to apply to * <a href="package-summary.html#Statelessness">stateless</a>
* each element which produces an {@code IntStream} of new * function to apply to each element which produces an
* values * {@code IntStream} of new values
* @return the new stream * @return the new stream
* @see Stream#flatMap(Function) * @see Stream#flatMap(Function)
*/ */
...@@ -421,9 +356,10 @@ public interface IntStream extends BaseStream<Integer, IntStream> { ...@@ -421,9 +356,10 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
* synchronization and with greatly reduced risk of data races. * synchronization and with greatly reduced risk of data races.
* *
* @param identity the identity value for the accumulating function * @param identity the identity value for the accumulating function
* @param op an <a href="package-summary.html#Associativity">associative</a> * @param op an <a href="package-summary.html#Associativity">associative</a>,
* <a href="package-summary.html#NonInterference">non-interfering, * <a href="package-summary.html#NonInterference">non-interfering</a>,
* stateless</a> function for combining two values * <a href="package-summary.html#Statelessness">stateless</a>
* function for combining two values
* @return the result of the reduction * @return the result of the reduction
* @see #sum() * @see #sum()
* @see #min() * @see #min()
...@@ -460,9 +396,10 @@ public interface IntStream extends BaseStream<Integer, IntStream> { ...@@ -460,9 +396,10 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
* <p>This is a <a href="package-summary.html#StreamOps">terminal * <p>This is a <a href="package-summary.html#StreamOps">terminal
* operation</a>. * operation</a>.
* *
* @param op an <a href="package-summary.html#Associativity">associative</a> * @param op an <a href="package-summary.html#Associativity">associative</a>,
* <a href="package-summary.html#NonInterference">non-interfering, * <a href="package-summary.html#NonInterference">non-interfering</a>,
* stateless</a> function for combining two values * <a href="package-summary.html#Statelessness">stateless</a>
* function for combining two values
* @return the result of the reduction * @return the result of the reduction
* @see #reduce(int, IntBinaryOperator) * @see #reduce(int, IntBinaryOperator)
*/ */
...@@ -492,14 +429,15 @@ public interface IntStream extends BaseStream<Integer, IntStream> { ...@@ -492,14 +429,15 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
* @param supplier a function that creates a new result container. For a * @param supplier a function that creates a new result container. For a
* parallel execution, this function may be called * parallel execution, this function may be called
* multiple times and must return a fresh value each time. * multiple times and must return a fresh value each time.
* @param accumulator an <a href="package-summary.html#Associativity">associative</a> * @param accumulator an <a href="package-summary.html#Associativity">associative</a>,
* <a href="package-summary.html#NonInterference">non-interfering, * <a href="package-summary.html#NonInterference">non-interfering</a>,
* stateless</a> function for incorporating an additional * <a href="package-summary.html#Statelessness">stateless</a>
* element into a result * function for incorporating an additional element into a result
* @param combiner an <a href="package-summary.html#Associativity">associative</a> * @param combiner an <a href="package-summary.html#Associativity">associative</a>,
* <a href="package-summary.html#NonInterference">non-interfering, * <a href="package-summary.html#NonInterference">non-interfering</a>,
* stateless</a> function for combining two values, which * <a href="package-summary.html#Statelessness">stateless</a>
* must be compatible with the accumulator function * function for combining two values, which must be
* compatible with the accumulator function
* @return the result of the reduction * @return the result of the reduction
* @see Stream#collect(Supplier, BiConsumer, BiConsumer) * @see Stream#collect(Supplier, BiConsumer, BiConsumer)
*/ */
...@@ -599,48 +537,67 @@ public interface IntStream extends BaseStream<Integer, IntStream> { ...@@ -599,48 +537,67 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
/** /**
* Returns whether any elements of this stream match the provided * Returns whether any elements of this stream match the provided
* predicate. May not evaluate the predicate on all elements if not * predicate. May not evaluate the predicate on all elements if not
* necessary for determining the result. * necessary for determining the result. If the stream is empty then
* {@code false} is returned and the predicate is not evaluated.
* *
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
* terminal operation</a>. * terminal operation</a>.
* *
* @param predicate a <a href="package-summary.html#NonInterference">non-interfering, * @apiNote
* stateless</a> predicate to apply to elements of this * This method evaluates the <em>existential quantification</em> of the
* stream * predicate over the elements of the stream (for some x P(x)).
*
* @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* predicate to apply to elements of this stream
* @return {@code true} if any elements of the stream match the provided * @return {@code true} if any elements of the stream match the provided
* predicate otherwise {@code false} * predicate, otherwise {@code false}
*/ */
boolean anyMatch(IntPredicate predicate); boolean anyMatch(IntPredicate predicate);
/** /**
* Returns whether all elements of this stream match the provided predicate. * Returns whether all elements of this stream match the provided predicate.
* May not evaluate the predicate on all elements if not necessary for * May not evaluate the predicate on all elements if not necessary for
* determining the result. * determining the result. If the stream is empty then {@code true} is
* returned and the predicate is not evaluated.
* *
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
* terminal operation</a>. * terminal operation</a>.
* *
* @param predicate a <a href="package-summary.html#NonInterference">non-interfering, * @apiNote
* stateless</a> predicate to apply to elements of this * This method evaluates the <em>universal quantification</em> of the
* stream * predicate over the elements of the stream (for all x P(x)). If the
* @return {@code true} if all elements of the stream match the provided * stream is empty, the quantification is said to be <em>vacuously
* predicate otherwise {@code false} * satisfied</em> and is always {@code true} (regardless of P(x)).
*
* @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* predicate to apply to elements of this stream
* @return {@code true} if either all elements of the stream match the
* provided predicate or the stream is empty, otherwise {@code false}
*/ */
boolean allMatch(IntPredicate predicate); boolean allMatch(IntPredicate predicate);
/** /**
* Returns whether no elements of this stream match the provided predicate. * Returns whether no elements of this stream match the provided predicate.
* May not evaluate the predicate on all elements if not necessary for * May not evaluate the predicate on all elements if not necessary for
* determining the result. * determining the result. If the stream is empty then {@code true} is
* returned and the predicate is not evaluated.
* *
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
* terminal operation</a>. * terminal operation</a>.
* *
* @param predicate a <a href="package-summary.html#NonInterference">non-interfering, * @apiNote
* stateless</a> predicate to apply to elements of this * This method evaluates the <em>universal quantification</em> of the
* stream * negated predicate over the elements of the stream (for all x ~P(x)). If
* @return {@code true} if no elements of the stream match the provided * the stream is empty, the quantification is said to be vacuously satisfied
* predicate otherwise {@code false} * and is always {@code true}, regardless of P(x).
*
* @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* predicate to apply to elements of this stream
* @return {@code true} if either no elements of the stream match the
* provided predicate or the stream is empty, otherwise {@code false}
*/ */
boolean noneMatch(IntPredicate predicate); boolean noneMatch(IntPredicate predicate);
...@@ -803,12 +760,12 @@ public interface IntStream extends BaseStream<Integer, IntStream> { ...@@ -803,12 +760,12 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
} }
/** /**
* Returns a sequential stream where each element is generated by * Returns an infinite sequential unordered stream where each element is
* the provided {@code IntSupplier}. This is suitable for generating * generated by the provided {@code IntSupplier}. This is suitable for
* constant streams, streams of random elements, etc. * generating constant streams, streams of random elements, etc.
* *
* @param s the {@code IntSupplier} for generated elements * @param s the {@code IntSupplier} for generated elements
* @return a new sequential {@code IntStream} * @return a new infinite sequential unordered {@code IntStream}
*/ */
public static IntStream generate(IntSupplier s) { public static IntStream generate(IntSupplier s) {
Objects.requireNonNull(s); Objects.requireNonNull(s);
...@@ -871,11 +828,16 @@ public interface IntStream extends BaseStream<Integer, IntStream> { ...@@ -871,11 +828,16 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
/** /**
* Creates a lazily concatenated stream whose elements are all the * Creates a lazily concatenated stream whose elements are all the
* elements of the first stream followed by all the elements of the * elements of the first stream followed by all the elements of the
* second stream. The resulting stream is ordered if both * second stream. The resulting stream is ordered if both
* of the input streams are ordered, and parallel if either of the input * of the input streams are ordered, and parallel if either of the input
* streams is parallel. When the resulting stream is closed, the close * streams is parallel. When the resulting stream is closed, the close
* handlers for both input streams are invoked. * handlers for both input streams are invoked.
* *
* @implNote
* Use caution when constructing streams from repeated concatenation.
* Accessing an element of a deeply concatenated stream can result in deep
* call chains, or even {@code StackOverflowException}.
*
* @param a the first stream * @param a the first stream
* @param b the second stream * @param b the second stream
* @return the concatenation of the two input streams * @return the concatenation of the two input streams
......
...@@ -51,9 +51,13 @@ import java.util.function.ObjLongConsumer; ...@@ -51,9 +51,13 @@ import java.util.function.ObjLongConsumer;
import java.util.function.Supplier; import java.util.function.Supplier;
/** /**
* A sequence of elements supporting sequential and parallel aggregate * A sequence of primitive long-valued elements supporting sequential and parallel
* operations. The following example illustrates an aggregate operation using * aggregate operations. This is the {@code long} primitive specialization of
* {@link Stream} and {@link LongStream}: * {@link Stream}.
*
* <p>The following example illustrates an aggregate operation using
* {@link Stream} and {@link LongStream}, computing the sum of the weights of the
* red widgets:
* *
* <pre>{@code * <pre>{@code
* long sum = widgets.stream() * long sum = widgets.stream()
...@@ -62,78 +66,13 @@ import java.util.function.Supplier; ...@@ -62,78 +66,13 @@ import java.util.function.Supplier;
* .sum(); * .sum();
* }</pre> * }</pre>
* *
* In this example, {@code widgets} is a {@code Collection<Widget>}. We create * See the class documentation for {@link Stream} and the package documentation
* a stream of {@code Widget} objects via {@link Collection#stream Collection.stream()}, * for <a href="package-summary.html">java.util.stream</a> for additional
* filter it to produce a stream containing only the red widgets, and then * specification of streams, stream operations, stream pipelines, and
* transform it into a stream of {@code long} values representing the weight of * parallelism.
* 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 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.
*
* <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 * @since 1.8
* @see Stream
* @see <a href="package-summary.html">java.util.stream</a> * @see <a href="package-summary.html">java.util.stream</a>
*/ */
public interface LongStream extends BaseStream<Long, LongStream> { public interface LongStream extends BaseStream<Long, LongStream> {
...@@ -145,9 +84,10 @@ public interface LongStream extends BaseStream<Long, LongStream> { ...@@ -145,9 +84,10 @@ public interface LongStream extends BaseStream<Long, LongStream> {
* <p>This is an <a href="package-summary.html#StreamOps">intermediate * <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>. * operation</a>.
* *
* @param predicate a <a href="package-summary.html#NonInterference"> * @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>,
* non-interfering, stateless</a> predicate to apply to * <a href="package-summary.html#Statelessness">stateless</a>
* each element to determine if it should be included * predicate to apply to each element to determine if it
* should be included
* @return the new stream * @return the new stream
*/ */
LongStream filter(LongPredicate predicate); LongStream filter(LongPredicate predicate);
...@@ -159,9 +99,9 @@ public interface LongStream extends BaseStream<Long, LongStream> { ...@@ -159,9 +99,9 @@ public interface LongStream extends BaseStream<Long, LongStream> {
* <p>This is an <a href="package-summary.html#StreamOps">intermediate * <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>. * operation</a>.
* *
* @param mapper a <a href="package-summary.html#NonInterference"> * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* non-interfering, stateless</a> function to apply to each * <a href="package-summary.html#Statelessness">stateless</a>
* element * function to apply to each element
* @return the new stream * @return the new stream
*/ */
LongStream map(LongUnaryOperator mapper); LongStream map(LongUnaryOperator mapper);
...@@ -174,9 +114,9 @@ public interface LongStream extends BaseStream<Long, LongStream> { ...@@ -174,9 +114,9 @@ public interface LongStream extends BaseStream<Long, LongStream> {
* intermediate operation</a>. * intermediate operation</a>.
* *
* @param <U> the element type of the new stream * @param <U> the element type of the new stream
* @param mapper a <a href="package-summary.html#NonInterference"> * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* non-interfering, stateless</a> function to apply to each * <a href="package-summary.html#Statelessness">stateless</a>
* element * function to apply to each element
* @return the new stream * @return the new stream
*/ */
<U> Stream<U> mapToObj(LongFunction<? extends U> mapper); <U> Stream<U> mapToObj(LongFunction<? extends U> mapper);
...@@ -188,9 +128,9 @@ public interface LongStream extends BaseStream<Long, LongStream> { ...@@ -188,9 +128,9 @@ public interface LongStream extends BaseStream<Long, LongStream> {
* <p>This is an <a href="package-summary.html#StreamOps">intermediate * <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>. * operation</a>.
* *
* @param mapper a <a href="package-summary.html#NonInterference"> * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* non-interfering, stateless</a> function to apply to each * <a href="package-summary.html#Statelessness">stateless</a>
* element * function to apply to each element
* @return the new stream * @return the new stream
*/ */
IntStream mapToInt(LongToIntFunction mapper); IntStream mapToInt(LongToIntFunction mapper);
...@@ -202,9 +142,9 @@ public interface LongStream extends BaseStream<Long, LongStream> { ...@@ -202,9 +142,9 @@ public interface LongStream extends BaseStream<Long, LongStream> {
* <p>This is an <a href="package-summary.html#StreamOps">intermediate * <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>. * operation</a>.
* *
* @param mapper a <a href="package-summary.html#NonInterference"> * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* non-interfering, stateless</a> function to apply to each * <a href="package-summary.html#Statelessness">stateless</a>
* element * function to apply to each element
* @return the new stream * @return the new stream
*/ */
DoubleStream mapToDouble(LongToDoubleFunction mapper); DoubleStream mapToDouble(LongToDoubleFunction mapper);
...@@ -219,10 +159,10 @@ public interface LongStream extends BaseStream<Long, LongStream> { ...@@ -219,10 +159,10 @@ public interface LongStream extends BaseStream<Long, LongStream> {
* <p>This is an <a href="package-summary.html#StreamOps">intermediate * <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>. * operation</a>.
* *
* @param mapper a <a href="package-summary.html#NonInterference"> * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* non-interfering, stateless</a> function to apply to * <a href="package-summary.html#Statelessness">stateless</a>
* each element which produces an {@code LongStream} of new * function to apply to each element which produces a
* values * {@code LongStream} of new values
* @return the new stream * @return the new stream
* @see Stream#flatMap(Function) * @see Stream#flatMap(Function)
*/ */
...@@ -421,9 +361,10 @@ public interface LongStream extends BaseStream<Long, LongStream> { ...@@ -421,9 +361,10 @@ public interface LongStream extends BaseStream<Long, LongStream> {
* synchronization and with greatly reduced risk of data races. * synchronization and with greatly reduced risk of data races.
* *
* @param identity the identity value for the accumulating function * @param identity the identity value for the accumulating function
* @param op an <a href="package-summary.html#Associativity">associative</a> * @param op an <a href="package-summary.html#Associativity">associative</a>,
* <a href="package-summary.html#NonInterference">non-interfering, * <a href="package-summary.html#NonInterference">non-interfering</a>,
* stateless</a> function for combining two values * <a href="package-summary.html#Statelessness">stateless</a>
* function for combining two values
* @return the result of the reduction * @return the result of the reduction
* @see #sum() * @see #sum()
* @see #min() * @see #min()
...@@ -460,9 +401,10 @@ public interface LongStream extends BaseStream<Long, LongStream> { ...@@ -460,9 +401,10 @@ public interface LongStream extends BaseStream<Long, LongStream> {
* <p>This is a <a href="package-summary.html#StreamOps">terminal * <p>This is a <a href="package-summary.html#StreamOps">terminal
* operation</a>. * operation</a>.
* *
* @param op an <a href="package-summary.html#Associativity">associative</a> * @param op an <a href="package-summary.html#Associativity">associative</a>,
* <a href="package-summary.html#NonInterference">non-interfering, * <a href="package-summary.html#NonInterference">non-interfering</a>,
* stateless</a> function for combining two values * <a href="package-summary.html#Statelessness">stateless</a>
* function for combining two values
* @return the result of the reduction * @return the result of the reduction
* @see #reduce(long, LongBinaryOperator) * @see #reduce(long, LongBinaryOperator)
*/ */
...@@ -492,14 +434,15 @@ public interface LongStream extends BaseStream<Long, LongStream> { ...@@ -492,14 +434,15 @@ public interface LongStream extends BaseStream<Long, LongStream> {
* @param supplier a function that creates a new result container. For a * @param supplier a function that creates a new result container. For a
* parallel execution, this function may be called * parallel execution, this function may be called
* multiple times and must return a fresh value each time. * multiple times and must return a fresh value each time.
* @param accumulator an <a href="package-summary.html#Associativity">associative</a> * @param accumulator an <a href="package-summary.html#Associativity">associative</a>,
* <a href="package-summary.html#NonInterference">non-interfering, * <a href="package-summary.html#NonInterference">non-interfering</a>,
* stateless</a> function for incorporating an additional * <a href="package-summary.html#Statelessness">stateless</a>
* element into a result * function for incorporating an additional element into a result
* @param combiner an <a href="package-summary.html#Associativity">associative</a> * @param combiner an <a href="package-summary.html#Associativity">associative</a>,
* <a href="package-summary.html#NonInterference">non-interfering, * <a href="package-summary.html#NonInterference">non-interfering</a>,
* stateless</a> function for combining two values, which * <a href="package-summary.html#Statelessness">stateless</a>
* must be compatible with the accumulator function * function for combining two values, which must be
* compatible with the accumulator function
* @return the result of the reduction * @return the result of the reduction
* @see Stream#collect(Supplier, BiConsumer, BiConsumer) * @see Stream#collect(Supplier, BiConsumer, BiConsumer)
*/ */
...@@ -599,48 +542,67 @@ public interface LongStream extends BaseStream<Long, LongStream> { ...@@ -599,48 +542,67 @@ public interface LongStream extends BaseStream<Long, LongStream> {
/** /**
* Returns whether any elements of this stream match the provided * Returns whether any elements of this stream match the provided
* predicate. May not evaluate the predicate on all elements if not * predicate. May not evaluate the predicate on all elements if not
* necessary for determining the result. * necessary for determining the result. If the stream is empty then
* {@code false} is returned and the predicate is not evaluated.
* *
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
* terminal operation</a>. * terminal operation</a>.
* *
* @param predicate a <a href="package-summary.html#NonInterference">non-interfering, * @apiNote
* stateless</a> predicate to apply to elements of this * This method evaluates the <em>existential quantification</em> of the
* stream * predicate over the elements of the stream (for some x P(x)).
*
* @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* predicate to apply to elements of this stream
* @return {@code true} if any elements of the stream match the provided * @return {@code true} if any elements of the stream match the provided
* predicate otherwise {@code false} * predicate, otherwise {@code false}
*/ */
boolean anyMatch(LongPredicate predicate); boolean anyMatch(LongPredicate predicate);
/** /**
* Returns whether all elements of this stream match the provided predicate. * Returns whether all elements of this stream match the provided predicate.
* May not evaluate the predicate on all elements if not necessary for * May not evaluate the predicate on all elements if not necessary for
* determining the result. * determining the result. If the stream is empty then {@code true} is
* returned and the predicate is not evaluated.
* *
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
* terminal operation</a>. * terminal operation</a>.
* *
* @param predicate a <a href="package-summary.html#NonInterference">non-interfering, * @apiNote
* stateless</a> predicate to apply to elements of this * This method evaluates the <em>universal quantification</em> of the
* stream * predicate over the elements of the stream (for all x P(x)). If the
* @return {@code true} if all elements of the stream match the provided * stream is empty, the quantification is said to be <em>vacuously
* predicate otherwise {@code false} * satisfied</em> and is always {@code true} (regardless of P(x)).
*
* @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* predicate to apply to elements of this stream
* @return {@code true} if either all elements of the stream match the
* provided predicate or the stream is empty, otherwise {@code false}
*/ */
boolean allMatch(LongPredicate predicate); boolean allMatch(LongPredicate predicate);
/** /**
* Returns whether no elements of this stream match the provided predicate. * Returns whether no elements of this stream match the provided predicate.
* May not evaluate the predicate on all elements if not necessary for * May not evaluate the predicate on all elements if not necessary for
* determining the result. * determining the result. If the stream is empty then {@code true} is
* returned and the predicate is not evaluated.
* *
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
* terminal operation</a>. * terminal operation</a>.
* *
* @param predicate a <a href="package-summary.html#NonInterference">non-interfering, * @apiNote
* stateless</a> predicate to apply to elements of this * This method evaluates the <em>universal quantification</em> of the
* stream * negated predicate over the elements of the stream (for all x ~P(x)). If
* @return {@code true} if no elements of the stream match the provided * the stream is empty, the quantification is said to be vacuously satisfied
* predicate otherwise {@code false} * and is always {@code true}, regardless of P(x).
*
* @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* predicate to apply to elements of this stream
* @return {@code true} if either no elements of the stream match the
* provided predicate or the stream is empty, otherwise {@code false}
*/ */
boolean noneMatch(LongPredicate predicate); boolean noneMatch(LongPredicate predicate);
...@@ -791,12 +753,12 @@ public interface LongStream extends BaseStream<Long, LongStream> { ...@@ -791,12 +753,12 @@ public interface LongStream extends BaseStream<Long, LongStream> {
} }
/** /**
* Returns a sequential stream where each element is generated by * Returns an infinite sequential unordered stream where each element is
* the provided {@code LongSupplier}. This is suitable for generating * generated by the provided {@code LongSupplier}. This is suitable for
* constant streams, streams of random elements, etc. * generating constant streams, streams of random elements, etc.
* *
* @param s the {@code LongSupplier} for generated elements * @param s the {@code LongSupplier} for generated elements
* @return a new sequential {@code LongStream} * @return a new infinite sequential unordered {@code LongStream}
*/ */
public static LongStream generate(LongSupplier s) { public static LongStream generate(LongSupplier s) {
Objects.requireNonNull(s); Objects.requireNonNull(s);
...@@ -874,11 +836,16 @@ public interface LongStream extends BaseStream<Long, LongStream> { ...@@ -874,11 +836,16 @@ public interface LongStream extends BaseStream<Long, LongStream> {
/** /**
* Creates a lazily concatenated stream whose elements are all the * Creates a lazily concatenated stream whose elements are all the
* elements of the first stream followed by all the elements of the * elements of the first stream followed by all the elements of the
* second stream. The resulting stream is ordered if both * second stream. The resulting stream is ordered if both
* of the input streams are ordered, and parallel if either of the input * of the input streams are ordered, and parallel if either of the input
* streams is parallel. When the resulting stream is closed, the close * streams is parallel. When the resulting stream is closed, the close
* handlers for both input streams are invoked. * handlers for both input streams are invoked.
* *
* @implNote
* Use caution when constructing streams from repeated concatenation.
* Accessing an element of a deeply concatenated stream can result in deep
* call chains, or even {@code StackOverflowException}.
*
* @param a the first stream * @param a the first stream
* @param b the second stream * @param b the second stream
* @return the concatenation of the two input streams * @return the concatenation of the two input streams
......
...@@ -241,6 +241,7 @@ interface Node<T> { ...@@ -241,6 +241,7 @@ interface Node<T> {
* @param action a consumer that is to be invoked with each * @param action a consumer that is to be invoked with each
* element in this {@code Node.OfPrimitive} * element in this {@code Node.OfPrimitive}
*/ */
@SuppressWarnings("overloads")
void forEach(T_CONS action); void forEach(T_CONS action);
@Override @Override
......
...@@ -579,6 +579,7 @@ class SpinedBuffer<E> ...@@ -579,6 +579,7 @@ class SpinedBuffer<E>
spineIndex = 0; spineIndex = 0;
} }
@SuppressWarnings("overloads")
public void forEach(T_CONS consumer) { public void forEach(T_CONS consumer) {
// completed chunks, if any // completed chunks, if any
for (int j = 0; j < spineIndex; j++) for (int j = 0; j < spineIndex; j++)
......
...@@ -67,6 +67,11 @@ import java.util.function.UnaryOperator; ...@@ -67,6 +67,11 @@ import java.util.function.UnaryOperator;
* transform it into a stream of {@code int} values representing the weight of * 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. * each red widget. Then this stream is summed to produce a total weight.
* *
* <p>In addition to {@code Stream}, which is a stream of object references,
* there are primitive specializations for {@link IntStream}, {@link LongStream},
* and {@link DoubleStream}, all of which are referred to as "streams" and
* conform to the characteristics and restrictions described here.
*
* <p>To perform a computation, stream * <p>To perform a computation, stream
* <a href="package-summary.html#StreamOps">operations</a> are composed into a * <a href="package-summary.html#StreamOps">operations</a> are composed into a
* <em>stream pipeline</em>. A stream pipeline consists of a source (which * <em>stream pipeline</em>. A stream pipeline consists of a source (which
...@@ -97,14 +102,21 @@ import java.util.function.UnaryOperator; ...@@ -97,14 +102,21 @@ import java.util.function.UnaryOperator;
* *
* <p>Most stream operations accept parameters that describe user-specified * <p>Most stream operations accept parameters that describe user-specified
* behavior, such as the lambda expression {@code w -> w.getWeight()} passed to * behavior, such as the lambda expression {@code w -> w.getWeight()} passed to
* {@code mapToInt} in the example above. Such parameters are always instances * {@code mapToInt} in the example above. To preserve correct behavior,
* of a <a href="../function/package-summary.html">functional interface</a> such * these <em>behavioral parameters</em>:
* <ul>
* <li>must be <a href="package-summary.html#NonInterference">non-interfering</a>
* (they do not modify the stream source); and</li>
* <li>in most cases must be <a href="package-summary.html#Statelessness">stateless</a>
* (their result should not depend on any state that might change during execution
* of the stream pipeline).</li>
* </ul>
*
* <p>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 * as {@link java.util.function.Function}, and are often lambda expressions or
* method references. These parameters can never be null, should not modify the * method references. Unless otherwise specified these parameters must be
* stream source, and should be * <em>non-null</em>.
* <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 * <p>A stream should be operated on (invoking an intermediate or terminal stream
* operation) only once. This rules out, for example, "forked" streams, where * operation) only once. This rules out, for example, "forked" streams, where
...@@ -134,6 +146,9 @@ import java.util.function.UnaryOperator; ...@@ -134,6 +146,9 @@ import java.util.function.UnaryOperator;
* *
* @param <T> the type of the stream elements * @param <T> the type of the stream elements
* @since 1.8 * @since 1.8
* @see IntStream
* @see LongStream
* @see DoubleStream
* @see <a href="package-summary.html">java.util.stream</a> * @see <a href="package-summary.html">java.util.stream</a>
*/ */
public interface Stream<T> extends BaseStream<T, Stream<T>> { public interface Stream<T> extends BaseStream<T, Stream<T>> {
...@@ -145,9 +160,10 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> { ...@@ -145,9 +160,10 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
* <p>This is an <a href="package-summary.html#StreamOps">intermediate * <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>. * operation</a>.
* *
* @param predicate a <a href="package-summary.html#NonInterference"> * @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>,
* non-interfering, stateless</a> predicate to apply to * <a href="package-summary.html#Statelessness">stateless</a>
* each element to determine if it should be included * predicate to apply to each element to determine if it
* should be included
* @return the new stream * @return the new stream
*/ */
Stream<T> filter(Predicate<? super T> predicate); Stream<T> filter(Predicate<? super T> predicate);
...@@ -160,9 +176,9 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> { ...@@ -160,9 +176,9 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
* operation</a>. * operation</a>.
* *
* @param <R> The element type of the new stream * @param <R> The element type of the new stream
* @param mapper a <a href="package-summary.html#NonInterference"> * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* non-interfering, stateless</a> function to apply to each * <a href="package-summary.html#Statelessness">stateless</a>
* element * function to apply to each element
* @return the new stream * @return the new stream
*/ */
<R> Stream<R> map(Function<? super T, ? extends R> mapper); <R> Stream<R> map(Function<? super T, ? extends R> mapper);
...@@ -174,9 +190,9 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> { ...@@ -174,9 +190,9 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
* <p>This is an <a href="package-summary.html#StreamOps"> * <p>This is an <a href="package-summary.html#StreamOps">
* intermediate operation</a>. * intermediate operation</a>.
* *
* @param mapper a <a href="package-summary.html#NonInterference"> * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* non-interfering, stateless</a> function to apply to each * <a href="package-summary.html#Statelessness">stateless</a>
* element * function to apply to each element
* @return the new stream * @return the new stream
*/ */
IntStream mapToInt(ToIntFunction<? super T> mapper); IntStream mapToInt(ToIntFunction<? super T> mapper);
...@@ -188,9 +204,9 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> { ...@@ -188,9 +204,9 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
* <p>This is an <a href="package-summary.html#StreamOps">intermediate * <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>. * operation</a>.
* *
* @param mapper a <a href="package-summary.html#NonInterference"> * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* non-interfering, stateless</a> function to apply to each * <a href="package-summary.html#Statelessness">stateless</a>
* element * function to apply to each element
* @return the new stream * @return the new stream
*/ */
LongStream mapToLong(ToLongFunction<? super T> mapper); LongStream mapToLong(ToLongFunction<? super T> mapper);
...@@ -202,9 +218,9 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> { ...@@ -202,9 +218,9 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
* <p>This is an <a href="package-summary.html#StreamOps">intermediate * <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>. * operation</a>.
* *
* @param mapper a <a href="package-summary.html#NonInterference"> * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* non-interfering, stateless</a> function to apply to each * <a href="package-summary.html#Statelessness">stateless</a>
* element * function to apply to each element
* @return the new stream * @return the new stream
*/ */
DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper); DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper);
...@@ -221,19 +237,33 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> { ...@@ -221,19 +237,33 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
* *
* @apiNote * @apiNote
* The {@code flatMap()} operation has the effect of applying a one-to-many * The {@code flatMap()} operation has the effect of applying a one-to-many
* tranformation to the elements of the stream, and then flattening the * transformation to the elements of the stream, and then flattening the
* resulting elements into a new stream. For example, if {@code orders} * resulting elements into a new stream.
* is a stream of purchase orders, and each purchase order contains a *
* collection of line items, then the following produces a stream of line * <p><b>Examples.</b>
* items: *
* <p>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 containing all the line items in all the orders:
* <pre>{@code
* orders.flatMap(order -> order.getLineItems().stream())...
* }</pre>
*
* <p>If {@code path} is the path to a file, then the following produces a
* stream of the {@code words} contained in that file:
* <pre>{@code * <pre>{@code
* orderStream.flatMap(order -> order.getLineItems().stream())... * Stream<String> lines = Files.lines(path, StandardCharsets.UTF_8);
* Stream<String> words = lines.flatMap(line -> Stream.of(line.split(" +")));
* }</pre> * }</pre>
* The {@code mapper} function passed to {@code flatMap} splits a line,
* using a simple regular expression, into an array of words, and then
* creates a stream of words from that array.
* *
* @param <R> The element type of the new stream * @param <R> The element type of the new stream
* @param mapper a <a href="package-summary.html#NonInterference"> * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* non-interfering, stateless</a> function to apply to each * <a href="package-summary.html#Statelessness">stateless</a>
* element which produces a stream of new values * function to apply to each element which produces a stream
* of new values
* @return the new stream * @return the new stream
*/ */
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper); <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
...@@ -248,10 +278,12 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> { ...@@ -248,10 +278,12 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
* <p>This is an <a href="package-summary.html#StreamOps">intermediate * <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>. * operation</a>.
* *
* @param mapper a <a href="package-summary.html#NonInterference"> * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* non-interfering, stateless</a> function to apply to each * <a href="package-summary.html#Statelessness">stateless</a>
* element which produces a stream of new values * function to apply to each element which produces a stream
* of new values
* @return the new stream * @return the new stream
* @see #flatMap(Function)
*/ */
IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper); IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper);
...@@ -265,10 +297,12 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> { ...@@ -265,10 +297,12 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
* <p>This is an <a href="package-summary.html#StreamOps">intermediate * <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>. * operation</a>.
* *
* @param mapper a <a href="package-summary.html#NonInterference"> * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* non-interfering, stateless</a> function to apply to * <a href="package-summary.html#Statelessness">stateless</a>
* each element which produces a stream of new values * function to apply to each element which produces a stream
* of new values
* @return the new stream * @return the new stream
* @see #flatMap(Function)
*/ */
LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper); LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper);
...@@ -282,10 +316,12 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> { ...@@ -282,10 +316,12 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
* <p>This is an <a href="package-summary.html#StreamOps">intermediate * <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>. * operation</a>.
* *
* @param mapper a <a href="package-summary.html#NonInterference"> * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* non-interfering, stateless</a> function to apply to each * <a href="package-summary.html#Statelessness">stateless</a>
* element which produces a stream of new values * function to apply to each element which produces a stream
* of new values
* @return the new stream * @return the new stream
* @see #flatMap(Function)
*/ */
DoubleStream flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper); DoubleStream flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper);
...@@ -293,9 +329,27 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> { ...@@ -293,9 +329,27 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
* Returns a stream consisting of the distinct elements (according to * Returns a stream consisting of the distinct elements (according to
* {@link Object#equals(Object)}) of this stream. * {@link Object#equals(Object)}) of this stream.
* *
* <p>For ordered streams, the selection of distinct elements is stable
* (for duplicated elements, the element appearing first in the encounter
* order is preserved.) For unordered streams, no stability guarantees
* are made.
*
* <p>This is a <a href="package-summary.html#StreamOps">stateful * <p>This is a <a href="package-summary.html#StreamOps">stateful
* intermediate operation</a>. * intermediate operation</a>.
* *
* @apiNote
* Preserving stability for {@code distinct()} in parallel pipelines is
* relatively expensive (requires that the operation act as a full barrier,
* with substantial buffering overhead), and stability is often not needed.
* Using an unordered stream source (such as {@link #generate(Supplier)})
* or removing the ordering constraint with {@link #unordered()} may result
* in significantly more efficient execution for {@code distinct()} in parallel
* pipelines, if the semantics of your situation permit. If consistency
* with encounter order is required, and you are experiencing poor performance
* or memory utilization with {@code distinct()} in parallel pipelines,
* switching to sequential execution with {@link #sequential()} may improve
* performance.
*
* @return the new stream * @return the new stream
*/ */
Stream<T> distinct(); Stream<T> distinct();
...@@ -306,6 +360,9 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> { ...@@ -306,6 +360,9 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
* {@code Comparable}, a {@code java.lang.ClassCastException} may be thrown * {@code Comparable}, a {@code java.lang.ClassCastException} may be thrown
* when the terminal operation is executed. * when the terminal operation is executed.
* *
* <p>For ordered streams, the sort is stable. For unordered streams, no
* stability guarantees are made.
*
* <p>This is a <a href="package-summary.html#StreamOps">stateful * <p>This is a <a href="package-summary.html#StreamOps">stateful
* intermediate operation</a>. * intermediate operation</a>.
* *
...@@ -317,12 +374,15 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> { ...@@ -317,12 +374,15 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
* Returns a stream consisting of the elements of this stream, sorted * Returns a stream consisting of the elements of this stream, sorted
* according to the provided {@code Comparator}. * according to the provided {@code Comparator}.
* *
* <p>For ordered streams, the sort is stable. For unordered streams, no
* stability guarantees are made.
*
* <p>This is a <a href="package-summary.html#StreamOps">stateful * <p>This is a <a href="package-summary.html#StreamOps">stateful
* intermediate operation</a>. * intermediate operation</a>.
* *
* @param comparator a <a href="package-summary.html#NonInterference"> * @param comparator a <a href="package-summary.html#NonInterference">non-interfering</a>,
* non-interfering, stateless</a> {@code Comparator} to * <a href="package-summary.html#Statelessness">stateless</a>
* be used to compare stream elements * {@code Comparator} to be used to compare stream elements
* @return the new stream * @return the new stream
*/ */
Stream<T> sorted(Comparator<? super T> comparator); Stream<T> sorted(Comparator<? super T> comparator);
...@@ -420,7 +480,8 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> { ...@@ -420,7 +480,8 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
* <p>This is a <a href="package-summary.html#StreamOps">terminal * <p>This is a <a href="package-summary.html#StreamOps">terminal
* operation</a>. * operation</a>.
* *
* <p>For parallel stream pipelines, this operation does <em>not</em> * <p>The behavior of this operation is explicitly nondeterministic.
* For parallel stream pipelines, this operation does <em>not</em>
* guarantee to respect the encounter order of the stream, as doing so * guarantee to respect the encounter order of the stream, as doing so
* would sacrifice the benefit of parallelism. For any given element, the * would sacrifice the benefit of parallelism. For any given element, the
* action may be performed at whatever time and in whatever thread the * action may be performed at whatever time and in whatever thread the
...@@ -433,13 +494,18 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> { ...@@ -433,13 +494,18 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
void forEach(Consumer<? super T> action); void forEach(Consumer<? super T> action);
/** /**
* Performs an action for each element of this stream, guaranteeing that * Performs an action for each element of this stream, in the encounter
* each element is processed in encounter order for streams that have a * order of the stream if the stream has a defined encounter order.
* defined encounter order.
* *
* <p>This is a <a href="package-summary.html#StreamOps">terminal * <p>This is a <a href="package-summary.html#StreamOps">terminal
* operation</a>. * operation</a>.
* *
* <p>This operation processes the elements one at a time, in encounter
* order if one exists. Performing the action for one element
* <a href="../concurrent/package-summary.html#MemoryVisibility"><i>happens-before</i></a>
* performing the action for subsequent elements, but for any given element,
* the action may be performed in whatever thread the library chooses.
*
* @param action 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 * non-interfering</a> action to perform on the elements
* @see #forEach(Consumer) * @see #forEach(Consumer)
...@@ -528,9 +594,10 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> { ...@@ -528,9 +594,10 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
* synchronization and with greatly reduced risk of data races. * synchronization and with greatly reduced risk of data races.
* *
* @param identity the identity value for the accumulating function * @param identity the identity value for the accumulating function
* @param accumulator an <a href="package-summary.html#Associativity">associative</a> * @param accumulator an <a href="package-summary.html#Associativity">associative</a>,
* <a href="package-summary.html#NonInterference">non-interfering, * <a href="package-summary.html#NonInterference">non-interfering</a>,
* stateless</a> function for combining two values * <a href="package-summary.html#Statelessness">stateless</a>
* function for combining two values
* @return the result of the reduction * @return the result of the reduction
*/ */
T reduce(T identity, BinaryOperator<T> accumulator); T reduce(T identity, BinaryOperator<T> accumulator);
...@@ -563,14 +630,15 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> { ...@@ -563,14 +630,15 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
* <p>This is a <a href="package-summary.html#StreamOps">terminal * <p>This is a <a href="package-summary.html#StreamOps">terminal
* operation</a>. * operation</a>.
* *
* @param accumulator an <a href="package-summary.html#Associativity">associative</a> * @param accumulator an <a href="package-summary.html#Associativity">associative</a>,
* <a href="package-summary.html#NonInterference">non-interfering, * <a href="package-summary.html#NonInterference">non-interfering</a>,
* stateless</a> function for combining two values * <a href="package-summary.html#Statelessness">stateless</a>
* function for combining two values
* @return an {@link Optional} describing 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 * @throws NullPointerException if the result of the reduction is null
* @see #reduce(Object, BinaryOperator) * @see #reduce(Object, BinaryOperator)
* @see #min(java.util.Comparator) * @see #min(Comparator)
* @see #max(java.util.Comparator) * @see #max(Comparator)
*/ */
Optional<T> reduce(BinaryOperator<T> accumulator); Optional<T> reduce(BinaryOperator<T> accumulator);
...@@ -608,14 +676,15 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> { ...@@ -608,14 +676,15 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
* *
* @param <U> The type of the result * @param <U> The type of the result
* @param identity the identity value for the combiner function * @param identity the identity value for the combiner function
* @param accumulator an <a href="package-summary.html#Associativity">associative</a> * @param accumulator an <a href="package-summary.html#Associativity">associative</a>,
* <a href="package-summary.html#NonInterference">non-interfering, * <a href="package-summary.html#NonInterference">non-interfering</a>,
* stateless</a> function for incorporating an additional * <a href="package-summary.html#Statelessness">stateless</a>
* element into a result * function for incorporating an additional element into a result
* @param combiner an <a href="package-summary.html#Associativity">associative</a> * @param combiner an <a href="package-summary.html#Associativity">associative</a>,
* <a href="package-summary.html#NonInterference">non-interfering, * <a href="package-summary.html#NonInterference">non-interfering</a>,
* stateless</a> function for combining two values, which * <a href="package-summary.html#Statelessness">stateless</a>
* must be compatible with the accumulator function * function for combining two values, which must be
* compatible with the accumulator function
* @return the result of the reduction * @return the result of the reduction
* @see #reduce(BinaryOperator) * @see #reduce(BinaryOperator)
* @see #reduce(Object, BinaryOperator) * @see #reduce(Object, BinaryOperator)
...@@ -664,14 +733,15 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> { ...@@ -664,14 +733,15 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
* @param supplier a function that creates a new result container. For a * @param supplier a function that creates a new result container. For a
* parallel execution, this function may be called * parallel execution, this function may be called
* multiple times and must return a fresh value each time. * multiple times and must return a fresh value each time.
* @param accumulator an <a href="package-summary.html#Associativity">associative</a> * @param accumulator an <a href="package-summary.html#Associativity">associative</a>,
* <a href="package-summary.html#NonInterference">non-interfering, * <a href="package-summary.html#NonInterference">non-interfering</a>,
* stateless</a> function for incorporating an additional * <a href="package-summary.html#Statelessness">stateless</a>
* element into a result * function for incorporating an additional element into a result
* @param combiner an <a href="package-summary.html#Associativity">associative</a> * @param combiner an <a href="package-summary.html#Associativity">associative</a>,
* <a href="package-summary.html#NonInterference">non-interfering, * <a href="package-summary.html#NonInterference">non-interfering</a>,
* stateless</a> function for combining two values, which * <a href="package-summary.html#Statelessness">stateless</a>
* must be compatible with the accumulator function * function for combining two values, which must be
* compatible with the accumulator function
* @return the result of the reduction * @return the result of the reduction
*/ */
<R> R collect(Supplier<R> supplier, <R> R collect(Supplier<R> supplier,
...@@ -687,6 +757,13 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> { ...@@ -687,6 +757,13 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
* collection strategies and composition of collect operations such as * collection strategies and composition of collect operations such as
* multiple-level grouping or partitioning. * multiple-level grouping or partitioning.
* *
* <p>If the stream is parallel, and the {@code Collector}
* is {@link Collector.Characteristics#CONCURRENT concurrent}, and
* either the stream is unordered or the collector is
* {@link Collector.Characteristics#UNORDERED unordered},
* then a concurrent reduction will be performed (see {@link Collector} for
* details on concurrent reduction.)
*
* <p>This is a <a href="package-summary.html#StreamOps">terminal * <p>This is a <a href="package-summary.html#StreamOps">terminal
* operation</a>. * operation</a>.
* *
...@@ -732,9 +809,9 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> { ...@@ -732,9 +809,9 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
* *
* <p>This is a <a href="package-summary.html#StreamOps">terminal operation</a>. * <p>This is a <a href="package-summary.html#StreamOps">terminal operation</a>.
* *
* @param comparator a <a href="package-summary.html#NonInterference">non-interfering, * @param comparator a <a href="package-summary.html#NonInterference">non-interfering</a>,
* stateless</a> {@code Comparator} to use to compare * <a href="package-summary.html#Statelessness">stateless</a>
* elements of this stream * {@code Comparator} to compare elements of this stream
* @return an {@code Optional} describing the minimum element of this stream, * @return an {@code Optional} describing the minimum element of this stream,
* or an empty {@code Optional} if the stream is empty * or an empty {@code Optional} if the stream is empty
* @throws NullPointerException if the minimum element is null * @throws NullPointerException if the minimum element is null
...@@ -749,9 +826,9 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> { ...@@ -749,9 +826,9 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
* <p>This is a <a href="package-summary.html#StreamOps">terminal * <p>This is a <a href="package-summary.html#StreamOps">terminal
* operation</a>. * operation</a>.
* *
* @param comparator a <a href="package-summary.html#NonInterference">non-interfering, * @param comparator a <a href="package-summary.html#NonInterference">non-interfering</a>,
* stateless</a> {@code Comparator} to use to compare * <a href="package-summary.html#Statelessness">stateless</a>
* elements of this stream * {@code Comparator} to compare elements of this stream
* @return an {@code Optional} describing the maximum element of this stream, * @return an {@code Optional} describing the maximum element of this stream,
* or an empty {@code Optional} if the stream is empty * or an empty {@code Optional} if the stream is empty
* @throws NullPointerException if the maximum element is null * @throws NullPointerException if the maximum element is null
...@@ -775,48 +852,67 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> { ...@@ -775,48 +852,67 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
/** /**
* Returns whether any elements of this stream match the provided * Returns whether any elements of this stream match the provided
* predicate. May not evaluate the predicate on all elements if not * predicate. May not evaluate the predicate on all elements if not
* necessary for determining the result. * necessary for determining the result. If the stream is empty then
* {@code false} is returned and the predicate is not evaluated.
* *
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
* terminal operation</a>. * terminal operation</a>.
* *
* @param predicate a <a href="package-summary.html#NonInterference">non-interfering, * @apiNote
* stateless</a> predicate to apply to elements of this * This method evaluates the <em>existential quantification</em> of the
* stream * predicate over the elements of the stream (for some x P(x)).
*
* @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* predicate to apply to elements of this stream
* @return {@code true} if any elements of the stream match the provided * @return {@code true} if any elements of the stream match the provided
* predicate otherwise {@code false} * predicate, otherwise {@code false}
*/ */
boolean anyMatch(Predicate<? super T> predicate); boolean anyMatch(Predicate<? super T> predicate);
/** /**
* Returns whether all elements of this stream match the provided predicate. * Returns whether all elements of this stream match the provided predicate.
* May not evaluate the predicate on all elements if not necessary for * May not evaluate the predicate on all elements if not necessary for
* determining the result. * determining the result. If the stream is empty then {@code true} is
* returned and the predicate is not evaluated.
* *
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
* terminal operation</a>. * terminal operation</a>.
* *
* @param predicate a <a href="package-summary.html#NonInterference">non-interfering, * @apiNote
* stateless</a> predicate to apply to elements of this * This method evaluates the <em>universal quantification</em> of the
* stream * predicate over the elements of the stream (for all x P(x)). If the
* @return {@code true} if all elements of the stream match the provided * stream is empty, the quantification is said to be <em>vacuously
* predicate otherwise {@code false} * satisfied</em> and is always {@code true} (regardless of P(x)).
*
* @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* predicate to apply to elements of this stream
* @return {@code true} if either all elements of the stream match the
* provided predicate or the stream is empty, otherwise {@code false}
*/ */
boolean allMatch(Predicate<? super T> predicate); boolean allMatch(Predicate<? super T> predicate);
/** /**
* Returns whether no elements of this stream match the provided predicate. * Returns whether no elements of this stream match the provided predicate.
* May not evaluate the predicate on all elements if not necessary for * May not evaluate the predicate on all elements if not necessary for
* determining the result. * determining the result. If the stream is empty then {@code true} is
* returned and the predicate is not evaluated.
* *
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
* terminal operation</a>. * terminal operation</a>.
* *
* @param predicate a <a href="package-summary.html#NonInterference">non-interfering, * @apiNote
* stateless</a> predicate to apply to elements of this * This method evaluates the <em>universal quantification</em> of the
* stream * negated predicate over the elements of the stream (for all x ~P(x)). If
* @return {@code true} if no elements of the stream match the provided * the stream is empty, the quantification is said to be vacuously satisfied
* predicate otherwise {@code false} * and is always {@code true}, regardless of P(x).
*
* @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* predicate to apply to elements of this stream
* @return {@code true} if either no elements of the stream match the
* provided predicate or the stream is empty, otherwise {@code false}
*/ */
boolean noneMatch(Predicate<? super T> predicate); boolean noneMatch(Predicate<? super T> predicate);
...@@ -939,13 +1035,13 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> { ...@@ -939,13 +1035,13 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
} }
/** /**
* Returns a sequential stream where each element is generated by * Returns an infinite sequential unordered stream where each element is
* the provided {@code Supplier}. This is suitable for generating * generated by the provided {@code Supplier}. This is suitable for
* constant streams, streams of random elements, etc. * generating constant streams, streams of random elements, etc.
* *
* @param <T> the type of stream elements * @param <T> the type of stream elements
* @param s the {@code Supplier} of generated elements * @param s the {@code Supplier} of generated elements
* @return a new sequential {@code Stream} * @return a new infinite sequential unordered {@code Stream}
*/ */
public static<T> Stream<T> generate(Supplier<T> s) { public static<T> Stream<T> generate(Supplier<T> s) {
Objects.requireNonNull(s); Objects.requireNonNull(s);
...@@ -956,11 +1052,16 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> { ...@@ -956,11 +1052,16 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
/** /**
* Creates a lazily concatenated stream whose elements are all the * Creates a lazily concatenated stream whose elements are all the
* elements of the first stream followed by all the elements of the * elements of the first stream followed by all the elements of the
* second stream. The resulting stream is ordered if both * second stream. The resulting stream is ordered if both
* of the input streams are ordered, and parallel if either of the input * of the input streams are ordered, and parallel if either of the input
* streams is parallel. When the resulting stream is closed, the close * streams is parallel. When the resulting stream is closed, the close
* handlers for both input streams are invoked. * handlers for both input streams are invoked.
* *
* @implNote
* Use caution when constructing streams from repeated concatenation.
* Accessing an element of a deeply concatenated stream can result in deep
* call chains, or even {@code StackOverflowException}.
*
* @param <T> The type of stream elements * @param <T> The type of stream elements
* @param a the first stream * @param a the first stream
* @param b the second stream * @param b the second stream
......
...@@ -96,7 +96,8 @@ public final class StreamSupport { ...@@ -96,7 +96,8 @@ public final class StreamSupport {
* @param supplier a {@code Supplier} of a {@code Spliterator} * @param supplier a {@code Supplier} of a {@code Spliterator}
* @param characteristics Spliterator characteristics of the supplied * @param characteristics Spliterator characteristics of the supplied
* {@code Spliterator}. The characteristics must be equal to * {@code Spliterator}. The characteristics must be equal to
* {@code supplier.get().characteristics()}. * {@code supplier.get().characteristics()}, otherwise undefined
* behavior may occur when terminal operation commences.
* @param parallel if {@code true} then the returned stream is a parallel * @param parallel if {@code true} then the returned stream is a parallel
* stream; if {@code false} the returned stream is a sequential * stream; if {@code false} the returned stream is a sequential
* stream. * stream.
...@@ -163,7 +164,8 @@ public final class StreamSupport { ...@@ -163,7 +164,8 @@ public final class StreamSupport {
* @param supplier a {@code Supplier} of a {@code Spliterator.OfInt} * @param supplier a {@code Supplier} of a {@code Spliterator.OfInt}
* @param characteristics Spliterator characteristics of the supplied * @param characteristics Spliterator characteristics of the supplied
* {@code Spliterator.OfInt}. The characteristics must be equal to * {@code Spliterator.OfInt}. The characteristics must be equal to
* {@code supplier.get().characteristics()} * {@code supplier.get().characteristics()}, otherwise undefined
* behavior may occur when terminal operation commences.
* @param parallel if {@code true} then the returned stream is a parallel * @param parallel if {@code true} then the returned stream is a parallel
* stream; if {@code false} the returned stream is a sequential * stream; if {@code false} the returned stream is a sequential
* stream. * stream.
...@@ -230,7 +232,8 @@ public final class StreamSupport { ...@@ -230,7 +232,8 @@ public final class StreamSupport {
* @param supplier a {@code Supplier} of a {@code Spliterator.OfLong} * @param supplier a {@code Supplier} of a {@code Spliterator.OfLong}
* @param characteristics Spliterator characteristics of the supplied * @param characteristics Spliterator characteristics of the supplied
* {@code Spliterator.OfLong}. The characteristics must be equal to * {@code Spliterator.OfLong}. The characteristics must be equal to
* {@code supplier.get().characteristics()} * {@code supplier.get().characteristics()}, otherwise undefined
* behavior may occur when terminal operation commences.
* @param parallel if {@code true} then the returned stream is a parallel * @param parallel if {@code true} then the returned stream is a parallel
* stream; if {@code false} the returned stream is a sequential * stream; if {@code false} the returned stream is a sequential
* stream. * stream.
...@@ -297,7 +300,8 @@ public final class StreamSupport { ...@@ -297,7 +300,8 @@ public final class StreamSupport {
* @param supplier A {@code Supplier} of a {@code Spliterator.OfDouble} * @param supplier A {@code Supplier} of a {@code Spliterator.OfDouble}
* @param characteristics Spliterator characteristics of the supplied * @param characteristics Spliterator characteristics of the supplied
* {@code Spliterator.OfDouble}. The characteristics must be equal to * {@code Spliterator.OfDouble}. The characteristics must be equal to
* {@code supplier.get().characteristics()} * {@code supplier.get().characteristics()}, otherwise undefined
* behavior may occur when terminal operation commences.
* @param parallel if {@code true} then the returned stream is a parallel * @param parallel if {@code true} then the returned stream is a parallel
* stream; if {@code false} the returned stream is a sequential * stream; if {@code false} the returned stream is a sequential
* stream. * stream.
......
...@@ -219,31 +219,18 @@ ...@@ -219,31 +219,18 @@
* <em>not modified at all</em> during the execution of the stream pipeline. * <em>not modified at all</em> during the execution of the stream pipeline.
* The notable exception to this are streams whose sources are concurrent * The notable exception to this are streams whose sources are concurrent
* collections, which are specifically designed to handle concurrent modification. * collections, which are specifically designed to handle concurrent modification.
* Concurrent stream sources are those whose {@code Spliterator} reports the
* {@code CONCURRENT} characteristic.
* *
* <p>Accordingly, behavioral parameters passed to stream methods should never * <p>Accordingly, behavioral parameters in stream pipelines whose source might
* modify the stream's data source. An implementation is said to * not be concurrent should never modify the stream's data source.
* <em>interfere</em> with the data source if it modifies, or causes to be * A behavioral parameter is said to <em>interfere</em> with a non-concurrent
* data source if it modifies, or causes to be
* modified, the stream's data source. The need for non-interference applies * modified, the stream's data source. The need for non-interference applies
* to all pipelines, not just parallel ones. Unless the stream source is * to all pipelines, not just parallel ones. Unless the stream source is
* concurrent, modifying a stream's data source during execution of a stream * concurrent, modifying a stream's data source during execution of a stream
* pipeline can cause exceptions, incorrect answers, or nonconformant behavior. * pipeline can cause exceptions, incorrect answers, or nonconformant behavior.
* *
* <p>Results may be nondeterministic or incorrect if the behavioral
* parameters of stream operations are <em>stateful</em>. A stateful lambda
* (or other object implementing the appropriate functional interface) is one
* whose result depends on any state which might change during the execution
* of the stream pipeline. An example of a stateful lambda is:
*
* <pre>{@code
* Set<Integer> seen = Collections.synchronizedSet(new HashSet<>());
* stream.parallel().map(e -> { if (seen.add(e)) return 0; else return e; })...
* }</pre>
*
* Here, if the mapping operation is performed in parallel, the results for the
* same input could vary from run to run, due to thread scheduling differences,
* whereas, with a stateless lambda expression the results would always be the
* same.
*
* For well-behaved stream sources, the source can be modified before the * For well-behaved stream sources, the source can be modified before the
* terminal operation commences and those modifications will be reflected in * terminal operation commences and those modifications will be reflected in
* the covered elements. For example, consider the following code: * the covered elements. For example, consider the following code:
...@@ -265,26 +252,54 @@ ...@@ -265,26 +252,54 @@
* <a href="package-summary.html#StreamSources">Low-level stream * <a href="package-summary.html#StreamSources">Low-level stream
* construction</a> for requirements for building well-behaved streams. * construction</a> for requirements for building well-behaved streams.
* *
* <p>Some streams, particularly those whose stream sources are concurrent, can * <h3><a name="Statelessness">Stateless behaviors</a></h3>
* tolerate concurrent modification during execution of a stream pipeline. *
* However, in no case -- even if the stream source is concurrent -- should * Stream pipeline results may be nondeterministic or incorrect if the behavioral
* behavioral parameters to stream operations modify the stream source. Modifying * parameters to the stream operations are <em>stateful</em>. A stateful lambda
* the stream source from within the stream source may cause pipeline execution * (or other object implementing the appropriate functional interface) is one
* to fail to terminate, produce inaccurate results, or throw exceptions. * whose result depends on any state which might change during the execution
* The following example shows inappropriate interference with the source: * of the stream pipeline. An example of a stateful lambda is the parameter
* to {@code map()} in:
*
* <pre>{@code * <pre>{@code
* // Don't do this! * Set<Integer> seen = Collections.synchronizedSet(new HashSet<>());
* List<String> l = new ArrayList(Arrays.asList("one", "two")); * stream.parallel().map(e -> { if (seen.add(e)) return 0; else return e; })...
* Stream<String> sl = l.stream();
* String s = sl.peek(s -> l.add("BAD LAMBDA")).collect(joining(" "));
* }</pre> * }</pre>
* *
* Here, if the mapping operation is performed in parallel, the results for the
* same input could vary from run to run, due to thread scheduling differences,
* whereas, with a stateless lambda expression the results would always be the
* same.
*
* <p>Note also that attempting to access mutable state from behavioral parameters
* presents you with a bad choice with respect to safety and performance; if
* you do not synchronize access to that state, you have a data race and
* therefore your code is broken, but if you do synchronize access to that
* state, you risk having contention undermine the parallelism you are seeking
* to benefit from. The best approach is to avoid stateful behavioral
* parameters to stream operations entirely; there is usually a way to
* restructure the stream pipeline to avoid statefulness.
*
* <h3>Side-effects</h3> * <h3>Side-effects</h3>
* *
* Side-effects in behavioral parameters to stream operations are, in general, * Side-effects in behavioral parameters to stream operations are, in general,
* discouraged, as they can often lead to unwitting violations of the * discouraged, as they can often lead to unwitting violations of the
* statelessness requirement, as well as other thread-safety hazards. Many * statelessness requirement, as well as other thread-safety hazards.
* computations where one might be tempted to use side effects can be more *
* <p>If the behavioral parameters do have side-effects, unless explicitly
* stated, there are no guarantees as to the
* <a href="../concurrent/package-summary.html#MemoryVisibility"><i>visibility</i></a>
* of those side-effects to other threads, nor are there any guarantees that
* different operations on the "same" element within the same stream pipeline
* are executed in the same thread. Further, the ordering of those effects
* may be surprising. Even when a pipeline is constrained to produce a
* <em>result</em> that is consistent with the encounter order of the stream
* source (for example, {@code IntStream.range(0,5).parallel().map(x -> x*2).toArray()}
* must produce {@code [0, 2, 4, 6, 8]}), no guarantees are made as to the order
* in which the mapper function is applied to individual elements, or in what
* thread any behavioral parameter is executed for a given element.
*
* <p>Many computations where one might be tempted to use side effects can be more
* safely and efficiently expressed without side-effects, such as using * safely and efficiently expressed without side-effects, such as using
* <a href="package-summary.html#Reduction">reduction</a> instead of mutable * <a href="package-summary.html#Reduction">reduction</a> instead of mutable
* accumulators. However, side-effects such as using {@code println()} for debugging * accumulators. However, side-effects such as using {@code println()} for debugging
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册