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
--- a/jdk/src/share/classes/java/lang/Iterable.java Tue Oct 22 14:51:08 2013 -0700
+++ b/jdk/src/share/classes/java/lang/Iterable.java Tue Oct 22 15:12:22 2013 -0700
@@ -51,10 +51,12 @@
Iterator<T> iterator();
/**
- * Performs the given action on the contents of the {@code Iterable}, in the
- * order elements occur when iterating, until all elements have been
- * processed or the action throws an exception. Errors or runtime
- * exceptions thrown by the action are relayed to the caller.
+ * Performs the given action for each element of the {@code Iterable}
+ * until all elements have been processed or the action throws an
+ * exception. Unless otherwise specified by the implementing class,
+ * 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
* <p>The default implementation behaves as if:
--- a/jdk/src/share/classes/java/lang/invoke/LambdaMetafactory.java Tue Oct 22 14:51:08 2013 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/LambdaMetafactory.java Tue Oct 22 15:12:22 2013 -0700
@@ -183,15 +183,15 @@
* @param samMethodType MethodType of the method in the functional interface
* to which the lambda or method reference is being
* converted, represented as a MethodType.
- * @param implMethod The implementation method which should be called
- * (with suitable adaptation of argument types, return
- * types, and adjustment for captured arguments) when
- * methods of the resulting functional interface instance
- * are invoked.
+ * @param implMethod A direct method handle describing the implementation
+ * method which should be called (with suitable adaptation
+ * of argument types, return types, and adjustment for
+ * captured arguments) when methods of the resulting
+ * functional interface instance are invoked.
* @param instantiatedMethodType The signature of the primary functional
* interface method after type variables
* 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
* functional interface
* @throws ReflectiveOperationException if the caller is not able to
@@ -220,15 +220,21 @@
* references to functional interfaces, which supports serialization and
* 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,
* String invokedName,
* MethodType invokedType,
* 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,
* String invokedName,
* MethodType invokedType,
@@ -241,7 +247,15 @@
* int bridgeCount, // 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
* with the accessibility privileges of the caller.
@@ -257,7 +271,7 @@
* In the event that the implementation method is an
* instance method, the first argument in the invocation
* 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
* functional interface
* @throws ReflectiveOperationException if the caller is not able to
--- a/jdk/src/share/classes/java/lang/invoke/SerializedLambda.java Tue Oct 22 14:51:08 2013 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/SerializedLambda.java Tue Oct 22 15:12:22 2013 -0700
@@ -32,9 +32,26 @@
import java.util.Objects;
/**
- * Serialized form of a lambda expression. The properties of this class represent the information that is present
- * at the lambda factory site, including the identity of the primary functional interface method, the identity of the
- * implementation method, and any variables captured from the local environment at the time of lambda capture.
+ * Serialized form of a lambda expression. The properties of this class
+ * represent the information that is present at the lambda factory site, including
+ * 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
*/
--- a/jdk/src/share/classes/java/util/DoubleSummaryStatistics.java Tue Oct 22 14:51:08 2013 -0700
+++ b/jdk/src/share/classes/java/util/DoubleSummaryStatistics.java Tue Oct 22 15:12:22 2013 -0700
@@ -127,7 +127,7 @@
* numerical sum compared to a simple summation of {@code double}
* values.
*
- * @apiNote Sorting values by increasing absolute magnitude tends to yield
+ * @apiNote Values sorted by increasing absolute magnitude tend to yield
* more accurate results.
*
* @return the sum of values, or zero if none
--- a/jdk/src/share/classes/java/util/Iterator.java Tue Oct 22 14:51:08 2013 -0700
+++ b/jdk/src/share/classes/java/util/Iterator.java Tue Oct 22 15:12:22 2013 -0700
@@ -94,10 +94,10 @@
}
/**
- * Performs the given action for each remaining element, in the order
- * elements occur when iterating, until all elements have been processed or
- * the action throws an exception. Errors or runtime exceptions thrown by
- * the action are relayed to the caller.
+ * Performs the given action for each remaining element until all elements
+ * have been processed or the action throws an exception. Actions are
+ * performed in the order of iteration, if that order is specified.
+ * Exceptions thrown by the action are relayed to the caller.
*
* @implSpec
* <p>The default implementation behaves as if:
--- a/jdk/src/share/classes/java/util/List.java Tue Oct 22 14:51:08 2013 -0700
+++ b/jdk/src/share/classes/java/util/List.java Tue Oct 22 15:12:22 2013 -0700
@@ -192,8 +192,9 @@
* The following code can be used to dump the list into a newly
* allocated array of <tt>String</tt>:
*
- * <pre>
- * String[] y = x.toArray(new String[0]);</pre>
+ * <pre>{@code
+ * String[] y = x.toArray(new String[0]);
+ * }</pre>
*
* Note that <tt>toArray(new Object[0])</tt> is identical in function to
* <tt>toArray()</tt>.
@@ -383,14 +384,13 @@
*
* @implSpec
* The default implementation is equivalent to, for this {@code list}:
- * <pre>
- * {@code
- * final ListIterator<E> li = list.listIterator();
- * while (li.hasNext()) {
- * li.set(operator.apply(li.next()));
- * }
- * }
- * </pre>
+ * <pre>{@code
+ * final ListIterator<E> li = list.listIterator();
+ * while (li.hasNext()) {
+ * li.set(operator.apply(li.next()));
+ * }
+ * }</pre>
+ *
* If the list's list-iterator does not support the {@code set} operation
* then an {@code UnsupportedOperationException} will be thrown when
* replacing the first element.
@@ -469,11 +469,11 @@
/**
* Returns the hash code value for this list. The hash code of a list
* is defined to be the result of the following calculation:
- * <pre>
- * int hashCode = 1;
- * for (E e : list)
- * hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
- * </pre>
+ * <pre>{@code
+ * int hashCode = 1;
+ * for (E e : list)
+ * hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
+ * }</pre>
* This ensures that <tt>list1.equals(list2)</tt> implies that
* <tt>list1.hashCode()==list2.hashCode()</tt> for any two lists,
* <tt>list1</tt> and <tt>list2</tt>, as required by the general
@@ -640,9 +640,9 @@
* a list can be used as a range operation by passing a subList view
* instead of a whole list. For example, the following idiom
* removes a range of elements from a list:
- * <pre>
+ * <pre>{@code
* list.subList(from, to).clear();
- * </pre>
+ * }</pre>
* Similar idioms may be constructed for <tt>indexOf</tt> and
* <tt>lastIndexOf</tt>, and all of the algorithms in the
* <tt>Collections</tt> class can be applied to a subList.<p>
--- a/jdk/src/share/classes/java/util/Map.java Tue Oct 22 14:51:08 2013 -0700
+++ b/jdk/src/share/classes/java/util/Map.java Tue Oct 22 15:12:22 2013 -0700
@@ -562,9 +562,8 @@
// Defaultable methods
/**
- * Returns the value to which the specified key is mapped,
- * or {@code defaultValue} if this map contains no mapping
- * for the key.
+ * Returns the value to which the specified key is mapped, or
+ * {@code defaultValue} if this map contains no mapping for the key.
*
* <p>The default implementation makes no guarantees about synchronization
* or atomicity properties of this method. Any implementation providing
@@ -591,9 +590,10 @@
}
/**
- * Performs the given action on each entry in this map, in the order entries
- * are returned by an entry set iterator (which may be unspecified), until
- * all entries have been processed or the action throws an {@code Exception}.
+ * Performs the given action for each entry in this map until all entries
+ * have been processed or the action throws an exception. Unless
+ * 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.
*
* <p>The default implementation should be overridden by implementations if
@@ -636,9 +636,9 @@
/**
* 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
- * set iterator, until all entries have been processed or the function
- * throws an exception.
+ * function on that entry until all entries have been processed or the
+ * function throws an exception. Exceptions thrown by the function are
+ * relayed to the caller.
*
* <p>The default implementation makes no guarantees about synchronization
* or atomicity properties of this method. Any implementation providing
--- a/jdk/src/share/classes/java/util/PrimitiveIterator.java Tue Oct 22 14:51:08 2013 -0700
+++ b/jdk/src/share/classes/java/util/PrimitiveIterator.java Tue Oct 22 15:12:22 2013 -0700
@@ -76,6 +76,7 @@
* @param action The action to be performed for each element
* @throws NullPointerException if the specified action is null
*/
+ @SuppressWarnings("overloads")
void forEachRemaining(T_CONS action);
/**
@@ -93,10 +94,10 @@
int nextInt();
/**
- * Performs the given action for each remaining element, in the order
- * elements occur when iterating, until all elements have been processed
- * or the action throws an exception. Errors or runtime exceptions
- * thrown by the action are relayed to the caller.
+ * Performs the given action for each remaining element until all elements
+ * have been processed or the action throws an exception. Actions are
+ * performed in the order of iteration, if that order is specified.
+ * Exceptions thrown by the action are relayed to the caller.
*
* @implSpec
* <p>The default implementation behaves as if:
@@ -167,10 +168,10 @@
long nextLong();
/**
- * Performs the given action for each remaining element, in the order
- * elements occur when iterating, until all elements have been processed
- * or the action throws an exception. Errors or runtime exceptions
- * thrown by the action are relayed to the caller.
+ * Performs the given action for each remaining element until all elements
+ * have been processed or the action throws an exception. Actions are
+ * performed in the order of iteration, if that order is specified.
+ * Exceptions thrown by the action are relayed to the caller.
*
* @implSpec
* <p>The default implementation behaves as if:
@@ -240,10 +241,10 @@
double nextDouble();
/**
- * Performs the given action for each remaining element, in the order
- * elements occur when iterating, until all elements have been processed
- * or the action throws an exception. Errors or runtime exceptions
- * thrown by the action are relayed to the caller.
+ * Performs the given action for each remaining element until all elements
+ * have been processed or the action throws an exception. Actions are
+ * performed in the order of iteration, if that order is specified.
+ * Exceptions thrown by the action are relayed to the caller.
*
* @implSpec
* <p>The default implementation behaves as if:
--- a/jdk/src/share/classes/java/util/Spliterator.java Tue Oct 22 14:51:08 2013 -0700
+++ b/jdk/src/share/classes/java/util/Spliterator.java Tue Oct 22 15:12:22 2013 -0700
@@ -613,6 +613,7 @@
* upon entry to this method, else {@code true}.
* @throws NullPointerException if the specified action is null
*/
+ @SuppressWarnings("overloads")
boolean tryAdvance(T_CONS action);
/**
@@ -630,6 +631,7 @@
* @param action The action
* @throws NullPointerException if the specified action is null
*/
+ @SuppressWarnings("overloads")
default void forEachRemaining(T_CONS action) {
do { } while (tryAdvance(action));
}
--- a/jdk/src/share/classes/java/util/function/package-info.java Tue Oct 22 14:51:08 2013 -0700
+++ b/jdk/src/share/classes/java/util/function/package-info.java Tue Oct 22 15:12:22 2013 -0700
@@ -60,7 +60,11 @@
* actions, or predicates. In documenting functional interfaces, or referring
* to variables typed as functional interfaces, it is common to refer directly
* 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
* convention, as follows:
--- a/jdk/src/share/classes/java/util/stream/BaseStream.java Tue Oct 22 14:51:08 2013 -0700
+++ b/jdk/src/share/classes/java/util/stream/BaseStream.java Tue Oct 22 15:12:22 2013 -0700
@@ -35,9 +35,10 @@
import java.util.function.Predicate;
/**
- * A sequence of elements supporting sequential and parallel aggregate
- * operations. The following example illustrates an aggregate operation using
- * {@link Stream} and {@link IntStream}:
+ * Base interface for streams, which are sequences of elements supporting
+ * sequential and parallel aggregate operations. The following example
+ * 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
* int sum = widgets.stream()
@@ -46,80 +47,18 @@
* .sum();
* }</pre>
*
- * In this example, {@code widgets} is a {@code Collection<Widget>}. We create
- * a stream of {@code Widget} objects via {@link Collection#stream Collection.stream()},
- * filter it to produce a stream containing only the red widgets, and then
- * transform it into a stream of {@code int} values representing the weight of
- * each red widget. Then this stream is summed to produce a total weight.
- *
- * <p>To perform a computation, stream
- * <a href="package-summary.html#StreamOps">operations</a> are composed into a
- * <em>stream pipeline</em>. A stream pipeline consists of a source (which
- * might be an array, a collection, a generator function, an IO channel,
- * etc), zero or more <em>intermediate operations</em> (which transform a
- * stream into another stream, such as {@link Stream#filter(Predicate)}), and a
- * <em>terminal operation</em> (which produces a result or side-effect, such
- * as {@link IntStream#sum()} or {@link IntStream#forEach(IntConsumer)}).
- * Streams are lazy; computation on the source data is only performed when the
- * terminal operation is initiated, and source elements are consumed only
- * as needed.
- *
- * <p>Collections and streams, while bearing some superficial similarities,
- * have different goals. Collections are primarily concerned with the efficient
- * management of, and access to, their elements. By contrast, streams do not
- * provide a means to directly access or manipulate their elements, and are
- * instead concerned with declaratively describing their source and the
- * computational operations which will be performed in aggregate on that source.
- * However, if the provided stream operations do not offer the desired
- * functionality, the {@link #iterator()} and {@link #spliterator()} operations
- * can be used to perform a controlled traversal.
- *
- * <p>A stream pipeline, like the "widgets" example above, can be viewed as
- * a <em>query</em> on the stream source. Unless the source was explicitly
- * designed for concurrent modification (such as a {@link ConcurrentHashMap}),
- * unpredictable or erroneous behavior may result from modifying the stream
- * source while it is being queried.
- *
- * <p>Most stream operations accept parameters that describe user-specified
- * behavior, such as the lambda expression {@code w -> w.getWeight()} passed to
- * {@code mapToInt} in the example above. Such parameters are always instances
- * of a <a href="../function/package-summary.html">functional interface</a> such
- * as {@link java.util.function.Function}, and are often lambda expressions or
- * method references. These parameters can never be null, should not modify the
- * stream source, and should be
- * <a href="package-summary.html#NonInterference">effectively stateless</a>
- * (their result should not depend on any state that might change during
- * execution of the stream pipeline.)
- *
- * <p>A stream should be operated on (invoking an intermediate or terminal stream
- * operation) only once. This rules out, for example, "forked" streams, where
- * the same source feeds two or more pipelines, or multiple traversals of the
- * same stream. A stream implementation may throw {@link IllegalStateException}
- * if it detects that the stream is being reused. However, since some stream
- * operations may return their receiver rather than a new stream object, it may
- * not be possible to detect reuse in all cases.
- *
- * <p>Streams have a {@link #close()} method and implement {@link AutoCloseable},
- * but nearly all stream instances do not actually need to be closed after use.
- * Generally, only streams whose source is an IO channel (such as those returned
- * by {@link Files#lines(Path, Charset)}) will require closing. Most streams
- * are backed by collections, arrays, or generating functions, which require no
- * special resource management. (If a stream does require closing, it can be
- * declared as a resource in a {@code try}-with-resources statement.)
- *
- * <p>Stream pipelines may execute either sequentially or in
- * <a href="package-summary.html#Parallelism">parallel</a>. This
- * execution mode is a property of the stream. Streams are created
- * with an initial choice of sequential or parallel execution. (For example,
- * {@link Collection#stream() Collection.stream()} creates a sequential stream,
- * and {@link Collection#parallelStream() Collection.parallelStream()} creates
- * a parallel one.) This choice of execution mode may be modified by the
- * {@link #sequential()} or {@link #parallel()} methods, and may be queried with
- * the {@link #isParallel()} method.
+ * See the class documentation for {@link Stream} and the package documentation
+ * for <a href="package-summary.html">java.util.stream</a> for additional
+ * specification of streams, stream operations, stream pipelines, and
+ * parallelism, which governs the behavior of all stream types.
*
* @param <T> the type of the stream elements
* @param <S> the type of of the stream implementing {@code BaseStream}
* @since 1.8
+ * @see Stream
+ * @see IntStream
+ * @see LongStream
+ * @see DoubleStream
* @see <a href="package-summary.html">java.util.stream</a>
*/
public interface BaseStream<T, S extends BaseStream<T, S>>
--- a/jdk/src/share/classes/java/util/stream/Collectors.java Tue Oct 22 14:51:08 2013 -0700
+++ b/jdk/src/share/classes/java/util/stream/Collectors.java Tue Oct 22 15:12:22 2013 -0700
@@ -462,7 +462,7 @@
*/
public static <T> Collector<T, ?, Integer>
summingInt(ToIntFunction<? super T> mapper) {
- return new CollectorImpl<T, int[], Integer>(
+ return new CollectorImpl<>(
() -> new int[1],
(a, t) -> { a[0] += mapper.applyAsInt(t); },
(a, b) -> { a[0] += b[0]; return a; },
@@ -480,7 +480,7 @@
*/
public static <T> Collector<T, ?, Long>
summingLong(ToLongFunction<? super T> mapper) {
- return new CollectorImpl<T, long[], Long>(
+ return new CollectorImpl<>(
() -> new long[1],
(a, t) -> { a[0] += mapper.applyAsLong(t); },
(a, b) -> { a[0] += b[0]; return a; },
@@ -505,7 +505,7 @@
*/
public static <T> Collector<T, ?, Double>
summingDouble(ToDoubleFunction<? super T> mapper) {
- return new CollectorImpl<T, double[], Double>(
+ return new CollectorImpl<>(
() -> new double[1],
(a, t) -> { a[0] += mapper.applyAsDouble(t); },
(a, b) -> { a[0] += b[0]; return a; },
@@ -523,7 +523,7 @@
*/
public static <T> Collector<T, ?, Double>
averagingInt(ToIntFunction<? super T> mapper) {
- return new CollectorImpl<T, long[], Double>(
+ return new CollectorImpl<>(
() -> new long[2],
(a, t) -> { a[0] += mapper.applyAsInt(t); a[1]++; },
(a, b) -> { a[0] += b[0]; a[1] += b[1]; return a; },
@@ -541,7 +541,7 @@
*/
public static <T> Collector<T, ?, Double>
averagingLong(ToLongFunction<? super T> mapper) {
- return new CollectorImpl<T, long[], Double>(
+ return new CollectorImpl<>(
() -> new long[2],
(a, t) -> { a[0] += mapper.applyAsLong(t); a[1]++; },
(a, b) -> { a[0] += b[0]; a[1] += b[1]; return a; },
@@ -566,7 +566,7 @@
*/
public static <T> Collector<T, ?, Double>
averagingDouble(ToDoubleFunction<? super T> mapper) {
- return new CollectorImpl<T, double[], Double>(
+ return new CollectorImpl<>(
() -> new double[2],
(a, t) -> { a[0] += mapper.applyAsDouble(t); a[1]++; },
(a, b) -> { a[0] += b[0]; a[1] += b[1]; return a; },
@@ -723,6 +723,14 @@
* groupingBy(classifier, toList());
* }</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 <K> the type of the keys
* @param classifier the classifier function mapping input elements to keys
@@ -759,6 +767,14 @@
* mapping(Person::getLastName, toSet())));
* }</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 <K> the type of the keys
* @param <A> the intermediate accumulation type of the downstream collector
@@ -798,6 +814,14 @@
* mapping(Person::getLastName, toSet())));
* }</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 <K> the type of the keys
* @param <A> the intermediate accumulation type of the downstream collector
@@ -871,7 +895,7 @@
* @param <T> the type of the input elements
* @param <K> the type of the 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 #groupingByConcurrent(Function, Collector)
@@ -912,7 +936,7 @@
* @param <D> the result type of the downstream reduction
* @param classifier a classifier function mapping input elements to keys
* @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 #groupingByConcurrent(Function)
@@ -958,7 +982,7 @@
* @param downstream a {@code Collector} implementing the downstream reduction
* @param mapFactory a function which, when called, produces a new empty
* {@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, Collector)
@@ -1072,7 +1096,7 @@
}
/**
- * 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
* mapping functions to the input elements.
*
@@ -1101,6 +1125,14 @@
* Functions.identity());
* }</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 <K> the output type of the key mapping function
* @param <U> the output type of the value mapping function
@@ -1121,7 +1153,7 @@
}
/**
- * 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
* mapping functions to the input elements.
*
@@ -1146,6 +1178,14 @@
* (s, a) -> s + ", " + a));
* }</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 <K> the output type of the key mapping function
* @param <U> the output type of the value mapping function
@@ -1172,7 +1212,7 @@
}
/**
- * 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
* mapping functions to the input elements.
*
@@ -1182,6 +1222,14 @@
* results are merged using the provided merging function. The {@code Map}
* 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 <K> the output type of the key mapping function
* @param <U> the output type of the value mapping function
@@ -1215,7 +1263,7 @@
}
/**
- * 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
* the provided mapping functions to the input elements.
*
@@ -1252,7 +1300,7 @@
* @param <U> the output type of the value mapping function
* @param keyMapper the mapping function to produce keys
* @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
* function to the input elements, and whose values are the result of
* applying a value mapping function to the input elements
@@ -1268,7 +1316,7 @@
}
/**
- * 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
* the provided mapping functions to the input elements.
*
@@ -1303,7 +1351,7 @@
* @param mergeFunction a merge function, used to resolve collisions between
* values associated with the same key, as supplied
* 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
* 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
@@ -1322,7 +1370,7 @@
}
/**
- * 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
* the provided mapping functions to the input elements.
*
@@ -1345,7 +1393,7 @@
* to {@link Map#merge(Object, Object, BiFunction)}
* @param mapSupplier a function which returns a new, empty {@code Map} into
* 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
* 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
--- a/jdk/src/share/classes/java/util/stream/DoubleStream.java Tue Oct 22 14:51:08 2013 -0700
+++ b/jdk/src/share/classes/java/util/stream/DoubleStream.java Tue Oct 22 15:12:22 2013 -0700
@@ -50,9 +50,13 @@
import java.util.function.Supplier;
/**
- * A sequence of elements supporting sequential and parallel aggregate
- * operations. The following example illustrates an aggregate operation using
- * {@link Stream} and {@link DoubleStream}:
+ * A sequence of primitive double-valued elements supporting sequential and parallel
+ * aggregate operations. This is the {@code double} primitive specialization of
+ * {@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
* double sum = widgets.stream()
@@ -61,78 +65,13 @@
* .sum();
* }</pre>
*
- * In this example, {@code widgets} is a {@code Collection<Widget>}. We create
- * a stream of {@code Widget} objects via {@link Collection#stream Collection.stream()},
- * filter it to produce a stream containing only the red widgets, and then
- * transform it into a stream of {@code double} values representing the weight of
- * each red widget. Then this stream is summed to produce a total weight.
- *
- * <p>To perform a computation, stream
- * <a href="package-summary.html#StreamOps">operations</a> are composed into a
- * <em>stream pipeline</em>. A stream pipeline consists of a source (which
- * might be an array, a collection, a generator function, an IO channel,
- * etc), zero or more <em>intermediate operations</em> (which transform a
- * stream into another stream, such as {@link 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.
+ * See the class documentation for {@link Stream} and the package documentation
+ * for <a href="package-summary.html">java.util.stream</a> for additional
+ * specification of streams, stream operations, stream pipelines, and
+ * parallelism.
*
* @since 1.8
+ * @see Stream
* @see <a href="package-summary.html">java.util.stream</a>
*/
public interface DoubleStream extends BaseStream<Double, DoubleStream> {
@@ -144,9 +83,10 @@
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>.
*
- * @param predicate a <a href="package-summary.html#NonInterference">
- * non-interfering, stateless</a> predicate to apply to
- * each element to determine if it should be included
+ * @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * predicate to apply to each element to determine if it
+ * should be included
* @return the new stream
*/
DoubleStream filter(DoublePredicate predicate);
@@ -158,9 +98,9 @@
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>.
*
- * @param mapper a <a href="package-summary.html#NonInterference">
- * non-interfering, stateless</a> function to apply to
- * each element
+ * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function to apply to each element
* @return the new stream
*/
DoubleStream map(DoubleUnaryOperator mapper);
@@ -173,9 +113,9 @@
* intermediate operation</a>.
*
* @param <U> the element type of the new stream
- * @param mapper a <a href="package-summary.html#NonInterference">
- * non-interfering, stateless</a> function to apply to each
- * element
+ * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function to apply to each element
* @return the new stream
*/
<U> Stream<U> mapToObj(DoubleFunction<? extends U> mapper);
@@ -187,9 +127,9 @@
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>.
*
- * @param mapper a <a href="package-summary.html#NonInterference">
- * non-interfering, stateless</a> function to apply to each
- * element
+ * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function to apply to each element
* @return the new stream
*/
IntStream mapToInt(DoubleToIntFunction mapper);
@@ -201,9 +141,9 @@
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>.
*
- * @param mapper a <a href="package-summary.html#NonInterference">
- * non-interfering, stateless</a> function to apply to each
- * element
+ * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function to apply to each element
* @return the new stream
*/
LongStream mapToLong(DoubleToLongFunction mapper);
@@ -218,10 +158,10 @@
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>.
*
- * @param mapper a <a href="package-summary.html#NonInterference">
- * non-interfering, stateless</a> function to apply to
- * each element which produces an {@code DoubleStream} of new
- * values
+ * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function to apply to each element which produces a
+ * {@code DoubleStream} of new values
* @return the new stream
* @see Stream#flatMap(Function)
*/
@@ -276,8 +216,8 @@
* }</pre>
*
* @param action a <a href="package-summary.html#NonInterference">
- * non-interfering</a> action to perform on the elements as
- * they are consumed from the stream
+ * non-interfering</a> action to perform on the elements as
+ * they are consumed from the stream
* @return the new stream
*/
DoubleStream peek(DoubleConsumer action);
@@ -423,9 +363,10 @@
* synchronization and with greatly reduced risk of data races.
*
* @param identity the identity value for the accumulating function
- * @param op an <a href="package-summary.html#Associativity">associative</a>
- * <a href="package-summary.html#NonInterference">non-interfering,
- * stateless</a> function for combining two values
+ * @param op an <a href="package-summary.html#Associativity">associative</a>,
+ * <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function for combining two values
* @return the result of the reduction
* @see #sum()
* @see #min()
@@ -462,9 +403,10 @@
* <p>This is a <a href="package-summary.html#StreamOps">terminal
* operation</a>.
*
- * @param op an <a href="package-summary.html#Associativity">associative</a>
- * <a href="package-summary.html#NonInterference">non-interfering,
- * stateless</a> function for combining two values
+ * @param op an <a href="package-summary.html#Associativity">associative</a>,
+ * <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function for combining two values
* @return the result of the reduction
* @see #reduce(double, DoubleBinaryOperator)
*/
@@ -495,14 +437,15 @@
* @param supplier a function that creates a new result container. For a
* parallel execution, this function may be called
* multiple times and must return a fresh value each time.
- * @param accumulator an <a href="package-summary.html#Associativity">associative</a>
- * <a href="package-summary.html#NonInterference">non-interfering,
- * stateless</a> function for incorporating an additional
- * element into a result
- * @param combiner an <a href="package-summary.html#Associativity">associative</a>
- * <a href="package-summary.html#NonInterference">non-interfering,
- * stateless</a> function for combining two values, which
- * must be compatible with the accumulator function
+ * @param accumulator an <a href="package-summary.html#Associativity">associative</a>,
+ * <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function for incorporating an additional element into a result
+ * @param combiner an <a href="package-summary.html#Associativity">associative</a>,
+ * <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function for combining two values, which must be
+ * compatible with the accumulator function
* @return the result of the reduction
* @see Stream#collect(Supplier, BiConsumer, BiConsumer)
*/
@@ -544,8 +487,8 @@
* <p>This is a <a href="package-summary.html#StreamOps">terminal
* operation</a>.
*
- * @apiNote Sorting values by increasing absolute magnitude tends to yield
- * more accurate results.
+ * @apiNote Elements sorted by increasing absolute magnitude tend
+ * to yield more accurate results.
*
* @return the sum of elements in this stream
*/
@@ -651,48 +594,67 @@
/**
* Returns whether any elements of this stream match the provided
* 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
* terminal operation</a>.
*
- * @param predicate a <a href="package-summary.html#NonInterference">non-interfering,
- * stateless</a> predicate to apply to elements of this
- * stream
+ * @apiNote
+ * This method evaluates the <em>existential quantification</em> of the
+ * 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
- * predicate otherwise {@code false}
+ * predicate, otherwise {@code false}
*/
boolean anyMatch(DoublePredicate predicate);
/**
* Returns whether all elements of this stream match the provided predicate.
* 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
* terminal operation</a>.
*
- * @param predicate a <a href="package-summary.html#NonInterference">non-interfering,
- * stateless</a> predicate to apply to elements of this
- * stream
- * @return {@code true} if all elements of the stream match the provided
- * predicate otherwise {@code false}
+ * @apiNote
+ * This method evaluates the <em>universal quantification</em> of the
+ * predicate over the elements of the stream (for all x P(x)). If the
+ * stream is empty, the quantification is said to be <em>vacuously
+ * 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);
/**
* Returns whether no elements of this stream match the provided predicate.
* 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
* terminal operation</a>.
*
- * @param predicate a <a href="package-summary.html#NonInterference">non-interfering,
- * stateless</a> predicate to apply to elements of this
- * stream
- * @return {@code true} if no elements of the stream match the provided
- * predicate otherwise {@code false}
+ * @apiNote
+ * This method evaluates the <em>universal quantification</em> of the
+ * negated predicate over the elements of the stream (for all x ~P(x)). If
+ * the stream is empty, the quantification is said to be vacuously satisfied
+ * 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);
@@ -832,12 +794,12 @@
}
/**
- * Returns a sequential stream where each element is generated by
- * the provided {@code DoubleSupplier}. This is suitable for generating
- * constant streams, streams of random elements, etc.
+ * Returns an infinite sequential unordered stream where each element is
+ * generated by the provided {@code DoubleSupplier}. This is suitable for
+ * generating constant streams, streams of random elements, etc.
*
* @param s the {@code DoubleSupplier} for generated elements
- * @return a new sequential {@code DoubleStream}
+ * @return a new infinite sequential unordered {@code DoubleStream}
*/
public static DoubleStream generate(DoubleSupplier s) {
Objects.requireNonNull(s);
@@ -848,11 +810,16 @@
/**
* Creates a lazily concatenated stream whose elements are all the
* elements of the first stream followed by all the elements of the
- * second stream. The resulting stream is ordered if both
+ * second stream. The resulting stream is ordered if both
* of the input streams are ordered, and parallel if either of the input
* streams is parallel. When the resulting stream is closed, the close
* handlers for both input streams are invoked.
*
+ * @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 b the second stream
* @return the concatenation of the two input streams
--- a/jdk/src/share/classes/java/util/stream/IntStream.java Tue Oct 22 14:51:08 2013 -0700
+++ b/jdk/src/share/classes/java/util/stream/IntStream.java Tue Oct 22 15:12:22 2013 -0700
@@ -24,11 +24,7 @@
*/
package java.util.stream;
-import java.nio.charset.Charset;
-import java.nio.file.Files;
-import java.nio.file.Path;
import java.util.Arrays;
-import java.util.Collection;
import java.util.IntSummaryStatistics;
import java.util.Objects;
import java.util.OptionalDouble;
@@ -36,7 +32,6 @@
import java.util.PrimitiveIterator;
import java.util.Spliterator;
import java.util.Spliterators;
-import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.IntBinaryOperator;
@@ -51,9 +46,13 @@
import java.util.function.Supplier;
/**
- * A sequence of elements supporting sequential and parallel aggregate
- * operations. The following example illustrates an aggregate operation using
- * {@link Stream} and {@link IntStream}:
+ * A sequence of primitive int-valued elements supporting sequential and parallel
+ * aggregate operations. This is the {@code int} primitive specialization of
+ * {@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
* int sum = widgets.stream()
@@ -62,78 +61,13 @@
* .sum();
* }</pre>
*
- * In this example, {@code widgets} is a {@code Collection<Widget>}. We create
- * a stream of {@code Widget} objects via {@link Collection#stream Collection.stream()},
- * filter it to produce a stream containing only the red widgets, and then
- * transform it into a stream of {@code int} values representing the weight of
- * each red widget. Then this stream is summed to produce a total weight.
- *
- * <p>To perform a computation, stream
- * <a href="package-summary.html#StreamOps">operations</a> are composed into a
- * <em>stream pipeline</em>. A stream pipeline consists of a source (which
- * might be an array, a collection, a generator function, an IO channel,
- * etc), zero or more <em>intermediate operations</em> (which transform a
- * stream into another stream, such as {@link 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.
+ * See the class documentation for {@link Stream} and the package documentation
+ * for <a href="package-summary.html">java.util.stream</a> for additional
+ * specification of streams, stream operations, stream pipelines, and
+ * parallelism.
*
* @since 1.8
+ * @see Stream
* @see <a href="package-summary.html">java.util.stream</a>
*/
public interface IntStream extends BaseStream<Integer, IntStream> {
@@ -145,9 +79,10 @@
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>.
*
- * @param predicate a <a href="package-summary.html#NonInterference">
- * non-interfering, stateless</a> predicate to apply to
- * each element to determine if it should be included
+ * @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * predicate to apply to each element to determine if it
+ * should be included
* @return the new stream
*/
IntStream filter(IntPredicate predicate);
@@ -159,9 +94,9 @@
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>.
*
- * @param mapper a <a href="package-summary.html#NonInterference">
- * non-interfering, stateless</a> function to apply to each
- * element
+ * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function to apply to each element
* @return the new stream
*/
IntStream map(IntUnaryOperator mapper);
@@ -174,9 +109,9 @@
* intermediate operation</a>.
*
* @param <U> the element type of the new stream
- * @param mapper a <a href="package-summary.html#NonInterference">
- * non-interfering, stateless</a> function to apply to each
- * element
+ * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function to apply to each element
* @return the new stream
*/
<U> Stream<U> mapToObj(IntFunction<? extends U> mapper);
@@ -188,9 +123,9 @@
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>.
*
- * @param mapper a <a href="package-summary.html#NonInterference">
- * non-interfering, stateless</a> function to apply to each
- * element
+ * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function to apply to each element
* @return the new stream
*/
LongStream mapToLong(IntToLongFunction mapper);
@@ -202,9 +137,9 @@
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>.
*
- * @param mapper a <a href="package-summary.html#NonInterference">
- * non-interfering, stateless</a> function to apply to each
- * element
+ * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function to apply to each element
* @return the new stream
*/
DoubleStream mapToDouble(IntToDoubleFunction mapper);
@@ -219,10 +154,10 @@
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>.
*
- * @param mapper a <a href="package-summary.html#NonInterference">
- * non-interfering, stateless</a> function to apply to
- * each element which produces an {@code IntStream} of new
- * values
+ * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function to apply to each element which produces an
+ * {@code IntStream} of new values
* @return the new stream
* @see Stream#flatMap(Function)
*/
@@ -421,9 +356,10 @@
* synchronization and with greatly reduced risk of data races.
*
* @param identity the identity value for the accumulating function
- * @param op an <a href="package-summary.html#Associativity">associative</a>
- * <a href="package-summary.html#NonInterference">non-interfering,
- * stateless</a> function for combining two values
+ * @param op an <a href="package-summary.html#Associativity">associative</a>,
+ * <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function for combining two values
* @return the result of the reduction
* @see #sum()
* @see #min()
@@ -460,9 +396,10 @@
* <p>This is a <a href="package-summary.html#StreamOps">terminal
* operation</a>.
*
- * @param op an <a href="package-summary.html#Associativity">associative</a>
- * <a href="package-summary.html#NonInterference">non-interfering,
- * stateless</a> function for combining two values
+ * @param op an <a href="package-summary.html#Associativity">associative</a>,
+ * <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function for combining two values
* @return the result of the reduction
* @see #reduce(int, IntBinaryOperator)
*/
@@ -492,14 +429,15 @@
* @param supplier a function that creates a new result container. For a
* parallel execution, this function may be called
* multiple times and must return a fresh value each time.
- * @param accumulator an <a href="package-summary.html#Associativity">associative</a>
- * <a href="package-summary.html#NonInterference">non-interfering,
- * stateless</a> function for incorporating an additional
- * element into a result
- * @param combiner an <a href="package-summary.html#Associativity">associative</a>
- * <a href="package-summary.html#NonInterference">non-interfering,
- * stateless</a> function for combining two values, which
- * must be compatible with the accumulator function
+ * @param accumulator an <a href="package-summary.html#Associativity">associative</a>,
+ * <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function for incorporating an additional element into a result
+ * @param combiner an <a href="package-summary.html#Associativity">associative</a>,
+ * <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function for combining two values, which must be
+ * compatible with the accumulator function
* @return the result of the reduction
* @see Stream#collect(Supplier, BiConsumer, BiConsumer)
*/
@@ -599,48 +537,67 @@
/**
* Returns whether any elements of this stream match the provided
* 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
* terminal operation</a>.
*
- * @param predicate a <a href="package-summary.html#NonInterference">non-interfering,
- * stateless</a> predicate to apply to elements of this
- * stream
+ * @apiNote
+ * This method evaluates the <em>existential quantification</em> of the
+ * 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
- * predicate otherwise {@code false}
+ * predicate, otherwise {@code false}
*/
boolean anyMatch(IntPredicate predicate);
/**
* Returns whether all elements of this stream match the provided predicate.
* 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
* terminal operation</a>.
*
- * @param predicate a <a href="package-summary.html#NonInterference">non-interfering,
- * stateless</a> predicate to apply to elements of this
- * stream
- * @return {@code true} if all elements of the stream match the provided
- * predicate otherwise {@code false}
+ * @apiNote
+ * This method evaluates the <em>universal quantification</em> of the
+ * predicate over the elements of the stream (for all x P(x)). If the
+ * stream is empty, the quantification is said to be <em>vacuously
+ * 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);
/**
* Returns whether no elements of this stream match the provided predicate.
* 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
* terminal operation</a>.
*
- * @param predicate a <a href="package-summary.html#NonInterference">non-interfering,
- * stateless</a> predicate to apply to elements of this
- * stream
- * @return {@code true} if no elements of the stream match the provided
- * predicate otherwise {@code false}
+ * @apiNote
+ * This method evaluates the <em>universal quantification</em> of the
+ * negated predicate over the elements of the stream (for all x ~P(x)). If
+ * the stream is empty, the quantification is said to be vacuously satisfied
+ * 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);
@@ -803,12 +760,12 @@
}
/**
- * Returns a sequential stream where each element is generated by
- * the provided {@code IntSupplier}. This is suitable for generating
- * constant streams, streams of random elements, etc.
+ * Returns an infinite sequential unordered stream where each element is
+ * generated by the provided {@code IntSupplier}. This is suitable for
+ * generating constant streams, streams of random elements, etc.
*
* @param s the {@code IntSupplier} for generated elements
- * @return a new sequential {@code IntStream}
+ * @return a new infinite sequential unordered {@code IntStream}
*/
public static IntStream generate(IntSupplier s) {
Objects.requireNonNull(s);
@@ -871,11 +828,16 @@
/**
* Creates a lazily concatenated stream whose elements are all the
* elements of the first stream followed by all the elements of the
- * second stream. The resulting stream is ordered if both
+ * second stream. The resulting stream is ordered if both
* of the input streams are ordered, and parallel if either of the input
* streams is parallel. When the resulting stream is closed, the close
* handlers for both input streams are invoked.
*
+ * @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 b the second stream
* @return the concatenation of the two input streams
--- a/jdk/src/share/classes/java/util/stream/LongStream.java Tue Oct 22 14:51:08 2013 -0700
+++ b/jdk/src/share/classes/java/util/stream/LongStream.java Tue Oct 22 15:12:22 2013 -0700
@@ -51,9 +51,13 @@
import java.util.function.Supplier;
/**
- * A sequence of elements supporting sequential and parallel aggregate
- * operations. The following example illustrates an aggregate operation using
- * {@link Stream} and {@link LongStream}:
+ * A sequence of primitive long-valued elements supporting sequential and parallel
+ * aggregate operations. This is the {@code long} primitive specialization of
+ * {@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
* long sum = widgets.stream()
@@ -62,78 +66,13 @@
* .sum();
* }</pre>
*
- * In this example, {@code widgets} is a {@code Collection<Widget>}. We create
- * a stream of {@code Widget} objects via {@link Collection#stream Collection.stream()},
- * filter it to produce a stream containing only the red widgets, and then
- * transform it into a stream of {@code long} values representing the weight of
- * each red widget. Then this stream is summed to produce a total weight.
- *
- * <p>To perform a computation, stream
- * <a href="package-summary.html#StreamOps">operations</a> are composed into a
- * <em>stream pipeline</em>. A stream pipeline consists of a source (which
- * might be an array, a collection, a generator function, an IO channel,
- * etc), zero or more <em>intermediate operations</em> (which transform a
- * stream into another stream, such as {@link 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.
+ * See the class documentation for {@link Stream} and the package documentation
+ * for <a href="package-summary.html">java.util.stream</a> for additional
+ * specification of streams, stream operations, stream pipelines, and
+ * parallelism.
*
* @since 1.8
+ * @see Stream
* @see <a href="package-summary.html">java.util.stream</a>
*/
public interface LongStream extends BaseStream<Long, LongStream> {
@@ -145,9 +84,10 @@
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>.
*
- * @param predicate a <a href="package-summary.html#NonInterference">
- * non-interfering, stateless</a> predicate to apply to
- * each element to determine if it should be included
+ * @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * predicate to apply to each element to determine if it
+ * should be included
* @return the new stream
*/
LongStream filter(LongPredicate predicate);
@@ -159,9 +99,9 @@
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>.
*
- * @param mapper a <a href="package-summary.html#NonInterference">
- * non-interfering, stateless</a> function to apply to each
- * element
+ * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function to apply to each element
* @return the new stream
*/
LongStream map(LongUnaryOperator mapper);
@@ -174,9 +114,9 @@
* intermediate operation</a>.
*
* @param <U> the element type of the new stream
- * @param mapper a <a href="package-summary.html#NonInterference">
- * non-interfering, stateless</a> function to apply to each
- * element
+ * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function to apply to each element
* @return the new stream
*/
<U> Stream<U> mapToObj(LongFunction<? extends U> mapper);
@@ -188,9 +128,9 @@
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>.
*
- * @param mapper a <a href="package-summary.html#NonInterference">
- * non-interfering, stateless</a> function to apply to each
- * element
+ * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function to apply to each element
* @return the new stream
*/
IntStream mapToInt(LongToIntFunction mapper);
@@ -202,9 +142,9 @@
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>.
*
- * @param mapper a <a href="package-summary.html#NonInterference">
- * non-interfering, stateless</a> function to apply to each
- * element
+ * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function to apply to each element
* @return the new stream
*/
DoubleStream mapToDouble(LongToDoubleFunction mapper);
@@ -219,10 +159,10 @@
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>.
*
- * @param mapper a <a href="package-summary.html#NonInterference">
- * non-interfering, stateless</a> function to apply to
- * each element which produces an {@code LongStream} of new
- * values
+ * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function to apply to each element which produces a
+ * {@code LongStream} of new values
* @return the new stream
* @see Stream#flatMap(Function)
*/
@@ -421,9 +361,10 @@
* synchronization and with greatly reduced risk of data races.
*
* @param identity the identity value for the accumulating function
- * @param op an <a href="package-summary.html#Associativity">associative</a>
- * <a href="package-summary.html#NonInterference">non-interfering,
- * stateless</a> function for combining two values
+ * @param op an <a href="package-summary.html#Associativity">associative</a>,
+ * <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function for combining two values
* @return the result of the reduction
* @see #sum()
* @see #min()
@@ -460,9 +401,10 @@
* <p>This is a <a href="package-summary.html#StreamOps">terminal
* operation</a>.
*
- * @param op an <a href="package-summary.html#Associativity">associative</a>
- * <a href="package-summary.html#NonInterference">non-interfering,
- * stateless</a> function for combining two values
+ * @param op an <a href="package-summary.html#Associativity">associative</a>,
+ * <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function for combining two values
* @return the result of the reduction
* @see #reduce(long, LongBinaryOperator)
*/
@@ -492,14 +434,15 @@
* @param supplier a function that creates a new result container. For a
* parallel execution, this function may be called
* multiple times and must return a fresh value each time.
- * @param accumulator an <a href="package-summary.html#Associativity">associative</a>
- * <a href="package-summary.html#NonInterference">non-interfering,
- * stateless</a> function for incorporating an additional
- * element into a result
- * @param combiner an <a href="package-summary.html#Associativity">associative</a>
- * <a href="package-summary.html#NonInterference">non-interfering,
- * stateless</a> function for combining two values, which
- * must be compatible with the accumulator function
+ * @param accumulator an <a href="package-summary.html#Associativity">associative</a>,
+ * <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function for incorporating an additional element into a result
+ * @param combiner an <a href="package-summary.html#Associativity">associative</a>,
+ * <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function for combining two values, which must be
+ * compatible with the accumulator function
* @return the result of the reduction
* @see Stream#collect(Supplier, BiConsumer, BiConsumer)
*/
@@ -599,48 +542,67 @@
/**
* Returns whether any elements of this stream match the provided
* 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
* terminal operation</a>.
*
- * @param predicate a <a href="package-summary.html#NonInterference">non-interfering,
- * stateless</a> predicate to apply to elements of this
- * stream
+ * @apiNote
+ * This method evaluates the <em>existential quantification</em> of the
+ * 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
- * predicate otherwise {@code false}
+ * predicate, otherwise {@code false}
*/
boolean anyMatch(LongPredicate predicate);
/**
* Returns whether all elements of this stream match the provided predicate.
* 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
* terminal operation</a>.
*
- * @param predicate a <a href="package-summary.html#NonInterference">non-interfering,
- * stateless</a> predicate to apply to elements of this
- * stream
- * @return {@code true} if all elements of the stream match the provided
- * predicate otherwise {@code false}
+ * @apiNote
+ * This method evaluates the <em>universal quantification</em> of the
+ * predicate over the elements of the stream (for all x P(x)). If the
+ * stream is empty, the quantification is said to be <em>vacuously
+ * 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);
/**
- * 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
- * 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
* terminal operation</a>.
*
- * @param predicate a <a href="package-summary.html#NonInterference">non-interfering,
- * stateless</a> predicate to apply to elements of this
- * stream
- * @return {@code true} if no elements of the stream match the provided
- * predicate otherwise {@code false}
+ * @apiNote
+ * This method evaluates the <em>universal quantification</em> of the
+ * negated predicate over the elements of the stream (for all x ~P(x)). If
+ * the stream is empty, the quantification is said to be vacuously satisfied
+ * 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);
@@ -791,12 +753,12 @@
}
/**
- * Returns a sequential stream where each element is generated by
- * the provided {@code LongSupplier}. This is suitable for generating
- * constant streams, streams of random elements, etc.
+ * Returns an infinite sequential unordered stream where each element is
+ * generated by the provided {@code LongSupplier}. This is suitable for
+ * generating constant streams, streams of random elements, etc.
*
* @param s the {@code LongSupplier} for generated elements
- * @return a new sequential {@code LongStream}
+ * @return a new infinite sequential unordered {@code LongStream}
*/
public static LongStream generate(LongSupplier s) {
Objects.requireNonNull(s);
@@ -874,11 +836,16 @@
/**
* Creates a lazily concatenated stream whose elements are all the
* elements of the first stream followed by all the elements of the
- * second stream. The resulting stream is ordered if both
+ * second stream. The resulting stream is ordered if both
* of the input streams are ordered, and parallel if either of the input
* streams is parallel. When the resulting stream is closed, the close
* handlers for both input streams are invoked.
*
+ * @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 b the second stream
* @return the concatenation of the two input streams
--- a/jdk/src/share/classes/java/util/stream/Node.java Tue Oct 22 14:51:08 2013 -0700
+++ b/jdk/src/share/classes/java/util/stream/Node.java Tue Oct 22 15:12:22 2013 -0700
@@ -241,6 +241,7 @@
* @param action a consumer that is to be invoked with each
* element in this {@code Node.OfPrimitive}
*/
+ @SuppressWarnings("overloads")
void forEach(T_CONS action);
@Override
--- a/jdk/src/share/classes/java/util/stream/SpinedBuffer.java Tue Oct 22 14:51:08 2013 -0700
+++ b/jdk/src/share/classes/java/util/stream/SpinedBuffer.java Tue Oct 22 15:12:22 2013 -0700
@@ -579,6 +579,7 @@
spineIndex = 0;
}
+ @SuppressWarnings("overloads")
public void forEach(T_CONS consumer) {
// completed chunks, if any
for (int j = 0; j < spineIndex; j++)
--- a/jdk/src/share/classes/java/util/stream/Stream.java Tue Oct 22 14:51:08 2013 -0700
+++ b/jdk/src/share/classes/java/util/stream/Stream.java Tue Oct 22 15:12:22 2013 -0700
@@ -67,6 +67,11 @@
* transform it into a stream of {@code int} values representing the weight of
* each red widget. Then this stream is summed to produce a total weight.
*
+ * <p>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
* <a href="package-summary.html#StreamOps">operations</a> are composed into a
* <em>stream pipeline</em>. A stream pipeline consists of a source (which
@@ -97,14 +102,21 @@
*
* <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
+ * {@code mapToInt} in the example above. To preserve correct behavior,
+ * 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
- * 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.)
+ * method references. Unless otherwise specified these parameters must be
+ * <em>non-null</em>.
*
* <p>A stream should be operated on (invoking an intermediate or terminal stream
* operation) only once. This rules out, for example, "forked" streams, where
@@ -134,6 +146,9 @@
*
* @param <T> the type of the stream elements
* @since 1.8
+ * @see IntStream
+ * @see LongStream
+ * @see DoubleStream
* @see <a href="package-summary.html">java.util.stream</a>
*/
public interface Stream<T> extends BaseStream<T, Stream<T>> {
@@ -145,9 +160,10 @@
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>.
*
- * @param predicate a <a href="package-summary.html#NonInterference">
- * non-interfering, stateless</a> predicate to apply to
- * each element to determine if it should be included
+ * @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * predicate to apply to each element to determine if it
+ * should be included
* @return the new stream
*/
Stream<T> filter(Predicate<? super T> predicate);
@@ -160,9 +176,9 @@
* operation</a>.
*
* @param <R> The element type of the new stream
- * @param mapper a <a href="package-summary.html#NonInterference">
- * non-interfering, stateless</a> function to apply to each
- * element
+ * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function to apply to each element
* @return the new stream
*/
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
@@ -174,9 +190,9 @@
* <p>This is an <a href="package-summary.html#StreamOps">
* intermediate operation</a>.
*
- * @param mapper a <a href="package-summary.html#NonInterference">
- * non-interfering, stateless</a> function to apply to each
- * element
+ * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function to apply to each element
* @return the new stream
*/
IntStream mapToInt(ToIntFunction<? super T> mapper);
@@ -188,9 +204,9 @@
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>.
*
- * @param mapper a <a href="package-summary.html#NonInterference">
- * non-interfering, stateless</a> function to apply to each
- * element
+ * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function to apply to each element
* @return the new stream
*/
LongStream mapToLong(ToLongFunction<? super T> mapper);
@@ -202,9 +218,9 @@
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>.
*
- * @param mapper a <a href="package-summary.html#NonInterference">
- * non-interfering, stateless</a> function to apply to each
- * element
+ * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function to apply to each element
* @return the new stream
*/
DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper);
@@ -221,19 +237,33 @@
*
* @apiNote
* The {@code flatMap()} operation has the effect of applying a one-to-many
- * tranformation to the elements of the stream, and then flattening the
- * resulting elements into a new stream. For example, if {@code orders}
- * is a stream of purchase orders, and each purchase order contains a
- * collection of line items, then the following produces a stream of line
- * items:
+ * transformation to the elements of the stream, and then flattening the
+ * resulting elements into a new stream.
+ *
+ * <p><b>Examples.</b>
+ *
+ * <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
- * orderStream.flatMap(order -> order.getLineItems().stream())...
+ * 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
+ * Stream<String> lines = Files.lines(path, StandardCharsets.UTF_8);
+ * Stream<String> words = lines.flatMap(line -> Stream.of(line.split(" +")));
+ * }</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 mapper a <a href="package-summary.html#NonInterference">
- * non-interfering, stateless</a> function to apply to each
- * element which produces a stream of new values
+ * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function to apply to each element which produces a stream
+ * of new values
* @return the new stream
*/
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
@@ -248,10 +278,12 @@
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>.
*
- * @param mapper a <a href="package-summary.html#NonInterference">
- * non-interfering, stateless</a> function to apply to each
- * element which produces a stream of new values
+ * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function to apply to each element which produces a stream
+ * of new values
* @return the new stream
+ * @see #flatMap(Function)
*/
IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper);
@@ -265,10 +297,12 @@
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>.
*
- * @param mapper a <a href="package-summary.html#NonInterference">
- * non-interfering, stateless</a> function to apply to
- * each element which produces a stream of new values
+ * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function to apply to each element which produces a stream
+ * of new values
* @return the new stream
+ * @see #flatMap(Function)
*/
LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper);
@@ -282,10 +316,12 @@
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>.
*
- * @param mapper a <a href="package-summary.html#NonInterference">
- * non-interfering, stateless</a> function to apply to each
- * element which produces a stream of new values
+ * @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function to apply to each element which produces a stream
+ * of new values
* @return the new stream
+ * @see #flatMap(Function)
*/
DoubleStream flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper);
@@ -293,9 +329,27 @@
* Returns a stream consisting of the distinct elements (according to
* {@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
* 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
*/
Stream<T> distinct();
@@ -306,6 +360,9 @@
* {@code Comparable}, a {@code java.lang.ClassCastException} may be thrown
* 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
* intermediate operation</a>.
*
@@ -317,12 +374,15 @@
* Returns a stream consisting of the elements of this stream, sorted
* 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
* intermediate operation</a>.
*
- * @param comparator a <a href="package-summary.html#NonInterference">
- * non-interfering, stateless</a> {@code Comparator} to
- * be used to compare stream elements
+ * @param comparator a <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * {@code Comparator} to be used to compare stream elements
* @return the new stream
*/
Stream<T> sorted(Comparator<? super T> comparator);
@@ -420,7 +480,8 @@
* <p>This is a <a href="package-summary.html#StreamOps">terminal
* 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
* would sacrifice the benefit of parallelism. For any given element, the
* action may be performed at whatever time and in whatever thread the
@@ -433,13 +494,18 @@
void forEach(Consumer<? super T> action);
/**
- * Performs an action for each element of this stream, guaranteeing that
- * each element is processed in encounter order for streams that have a
- * defined encounter order.
+ * Performs an action for each element of this stream, in the encounter
+ * order of the stream if the stream has a defined encounter order.
*
* <p>This is a <a href="package-summary.html#StreamOps">terminal
* 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">
* non-interfering</a> action to perform on the elements
* @see #forEach(Consumer)
@@ -528,9 +594,10 @@
* synchronization and with greatly reduced risk of data races.
*
* @param identity the identity value for the accumulating function
- * @param accumulator an <a href="package-summary.html#Associativity">associative</a>
- * <a href="package-summary.html#NonInterference">non-interfering,
- * stateless</a> function for combining two values
+ * @param accumulator an <a href="package-summary.html#Associativity">associative</a>,
+ * <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function for combining two values
* @return the result of the reduction
*/
T reduce(T identity, BinaryOperator<T> accumulator);
@@ -563,14 +630,15 @@
* <p>This is a <a href="package-summary.html#StreamOps">terminal
* operation</a>.
*
- * @param accumulator an <a href="package-summary.html#Associativity">associative</a>
- * <a href="package-summary.html#NonInterference">non-interfering,
- * stateless</a> function for combining two values
+ * @param accumulator an <a href="package-summary.html#Associativity">associative</a>,
+ * <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function for combining two values
* @return an {@link Optional} describing the result of the reduction
* @throws NullPointerException if the result of the reduction is null
* @see #reduce(Object, BinaryOperator)
- * @see #min(java.util.Comparator)
- * @see #max(java.util.Comparator)
+ * @see #min(Comparator)
+ * @see #max(Comparator)
*/
Optional<T> reduce(BinaryOperator<T> accumulator);
@@ -608,14 +676,15 @@
*
* @param <U> The type of the result
* @param identity the identity value for the combiner function
- * @param accumulator an <a href="package-summary.html#Associativity">associative</a>
- * <a href="package-summary.html#NonInterference">non-interfering,
- * stateless</a> function for incorporating an additional
- * element into a result
- * @param combiner an <a href="package-summary.html#Associativity">associative</a>
- * <a href="package-summary.html#NonInterference">non-interfering,
- * stateless</a> function for combining two values, which
- * must be compatible with the accumulator function
+ * @param accumulator an <a href="package-summary.html#Associativity">associative</a>,
+ * <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function for incorporating an additional element into a result
+ * @param combiner an <a href="package-summary.html#Associativity">associative</a>,
+ * <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function for combining two values, which must be
+ * compatible with the accumulator function
* @return the result of the reduction
* @see #reduce(BinaryOperator)
* @see #reduce(Object, BinaryOperator)
@@ -664,14 +733,15 @@
* @param supplier a function that creates a new result container. For a
* parallel execution, this function may be called
* multiple times and must return a fresh value each time.
- * @param accumulator an <a href="package-summary.html#Associativity">associative</a>
- * <a href="package-summary.html#NonInterference">non-interfering,
- * stateless</a> function for incorporating an additional
- * element into a result
- * @param combiner an <a href="package-summary.html#Associativity">associative</a>
- * <a href="package-summary.html#NonInterference">non-interfering,
- * stateless</a> function for combining two values, which
- * must be compatible with the accumulator function
+ * @param accumulator an <a href="package-summary.html#Associativity">associative</a>,
+ * <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function for incorporating an additional element into a result
+ * @param combiner an <a href="package-summary.html#Associativity">associative</a>,
+ * <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * function for combining two values, which must be
+ * compatible with the accumulator function
* @return the result of the reduction
*/
<R> R collect(Supplier<R> supplier,
@@ -687,6 +757,13 @@
* collection strategies and composition of collect operations such as
* 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
* operation</a>.
*
@@ -732,9 +809,9 @@
*
* <p>This is a <a href="package-summary.html#StreamOps">terminal operation</a>.
*
- * @param comparator a <a href="package-summary.html#NonInterference">non-interfering,
- * stateless</a> {@code Comparator} to use to compare
- * elements of this stream
+ * @param comparator a <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * {@code Comparator} to compare elements of this stream
* @return an {@code Optional} describing the minimum element of this stream,
* or an empty {@code Optional} if the stream is empty
* @throws NullPointerException if the minimum element is null
@@ -749,9 +826,9 @@
* <p>This is a <a href="package-summary.html#StreamOps">terminal
* operation</a>.
*
- * @param comparator a <a href="package-summary.html#NonInterference">non-interfering,
- * stateless</a> {@code Comparator} to use to compare
- * elements of this stream
+ * @param comparator a <a href="package-summary.html#NonInterference">non-interfering</a>,
+ * <a href="package-summary.html#Statelessness">stateless</a>
+ * {@code Comparator} to compare elements of this stream
* @return an {@code Optional} describing the maximum element of this stream,
* or an empty {@code Optional} if the stream is empty
* @throws NullPointerException if the maximum element is null
@@ -775,48 +852,67 @@
/**
* Returns whether any elements of this stream match the provided
* 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
* terminal operation</a>.
*
- * @param predicate a <a href="package-summary.html#NonInterference">non-interfering,
- * stateless</a> predicate to apply to elements of this
- * stream
+ * @apiNote
+ * This method evaluates the <em>existential quantification</em> of the
+ * 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
- * predicate otherwise {@code false}
+ * predicate, otherwise {@code false}
*/
boolean anyMatch(Predicate<? super T> predicate);
/**
* Returns whether all elements of this stream match the provided predicate.
* 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
* terminal operation</a>.
*
- * @param predicate a <a href="package-summary.html#NonInterference">non-interfering,
- * stateless</a> predicate to apply to elements of this
- * stream
- * @return {@code true} if all elements of the stream match the provided
- * predicate otherwise {@code false}
+ * @apiNote
+ * This method evaluates the <em>universal quantification</em> of the
+ * predicate over the elements of the stream (for all x P(x)). If the
+ * stream is empty, the quantification is said to be <em>vacuously
+ * 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);
/**
* Returns whether no elements of this stream match the provided predicate.
* 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
* terminal operation</a>.
*
- * @param predicate a <a href="package-summary.html#NonInterference">non-interfering,
- * stateless</a> predicate to apply to elements of this
- * stream
- * @return {@code true} if no elements of the stream match the provided
- * predicate otherwise {@code false}
+ * @apiNote
+ * This method evaluates the <em>universal quantification</em> of the
+ * negated predicate over the elements of the stream (for all x ~P(x)). If
+ * the stream is empty, the quantification is said to be vacuously satisfied
+ * 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);
@@ -939,13 +1035,13 @@
}
/**
- * Returns a sequential stream where each element is generated by
- * the provided {@code Supplier}. This is suitable for generating
- * constant streams, streams of random elements, etc.
+ * Returns an infinite sequential unordered stream where each element is
+ * generated by the provided {@code Supplier}. This is suitable for
+ * generating constant streams, streams of random elements, etc.
*
* @param <T> the type of stream elements
* @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) {
Objects.requireNonNull(s);
@@ -956,11 +1052,16 @@
/**
* Creates a lazily concatenated stream whose elements are all the
* elements of the first stream followed by all the elements of the
- * second stream. The resulting stream is ordered if both
+ * second stream. The resulting stream is ordered if both
* of the input streams are ordered, and parallel if either of the input
* streams is parallel. When the resulting stream is closed, the close
* handlers for both input streams are invoked.
*
+ * @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 a the first stream
* @param b the second stream
--- a/jdk/src/share/classes/java/util/stream/StreamSupport.java Tue Oct 22 14:51:08 2013 -0700
+++ b/jdk/src/share/classes/java/util/stream/StreamSupport.java Tue Oct 22 15:12:22 2013 -0700
@@ -96,7 +96,8 @@
* @param supplier a {@code Supplier} of a {@code Spliterator}
* @param characteristics Spliterator characteristics of the supplied
* {@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
* stream; if {@code false} the returned stream is a sequential
* stream.
@@ -163,7 +164,8 @@
* @param supplier a {@code Supplier} of a {@code Spliterator.OfInt}
* @param characteristics Spliterator characteristics of the supplied
* {@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
* stream; if {@code false} the returned stream is a sequential
* stream.
@@ -230,7 +232,8 @@
* @param supplier a {@code Supplier} of a {@code Spliterator.OfLong}
* @param characteristics Spliterator characteristics of the supplied
* {@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
* stream; if {@code false} the returned stream is a sequential
* stream.
@@ -297,7 +300,8 @@
* @param supplier A {@code Supplier} of a {@code Spliterator.OfDouble}
* @param characteristics Spliterator characteristics of the supplied
* {@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
* stream; if {@code false} the returned stream is a sequential
* stream.
--- a/jdk/src/share/classes/java/util/stream/package-info.java Tue Oct 22 14:51:08 2013 -0700
+++ b/jdk/src/share/classes/java/util/stream/package-info.java Tue Oct 22 15:12:22 2013 -0700
@@ -219,31 +219,18 @@
* <em>not modified at all</em> during the execution of the stream pipeline.
* The notable exception to this are streams whose sources are concurrent
* 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
- * modify the stream's data source. An implementation is said to
- * <em>interfere</em> with the data source if it modifies, or causes to be
+ * <p>Accordingly, behavioral parameters in stream pipelines whose source might
+ * not be concurrent should never modify the stream's data source.
+ * 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
* to all pipelines, not just parallel ones. Unless the stream source is
* concurrent, modifying a stream's data source during execution of a stream
* 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
* terminal operation commences and those modifications will be reflected in
* the covered elements. For example, consider the following code:
@@ -265,26 +252,54 @@
* <a href="package-summary.html#StreamSources">Low-level stream
* construction</a> for requirements for building well-behaved streams.
*
- * <p>Some streams, particularly those whose stream sources are concurrent, can
- * tolerate concurrent modification during execution of a stream pipeline.
- * However, in no case -- even if the stream source is concurrent -- should
- * behavioral parameters to stream operations modify the stream source. Modifying
- * the stream source from within the stream source may cause pipeline execution
- * to fail to terminate, produce inaccurate results, or throw exceptions.
- * The following example shows inappropriate interference with the source:
+ * <h3><a name="Statelessness">Stateless behaviors</a></h3>
+ *
+ * Stream pipeline results may be nondeterministic or incorrect if the behavioral
+ * parameters to the 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 the parameter
+ * to {@code map()} in:
+ *
* <pre>{@code
- * // Don't do this!
- * List<String> l = new ArrayList(Arrays.asList("one", "two"));
- * Stream<String> sl = l.stream();
- * String s = sl.peek(s -> l.add("BAD LAMBDA")).collect(joining(" "));
+ * 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.
+ *
+ * <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>
*
* Side-effects in behavioral parameters to stream operations are, in general,
* discouraged, as they can often lead to unwitting violations of the
- * statelessness requirement, as well as other thread-safety hazards. Many
- * computations where one might be tempted to use side effects can be more
+ * statelessness requirement, as well as other thread-safety hazards.
+ *
+ * <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
* <a href="package-summary.html#Reduction">reduction</a> instead of mutable
* accumulators. However, side-effects such as using {@code println()} for debugging