changeset 7728:9592b7987cac

Spec updates
author briangoetz
date Fri, 22 Mar 2013 19:22:04 -0400
parents ec9ba77a90bc
children 0172ddb6e113
files src/share/classes/java/util/stream/Stream.java src/share/classes/java/util/stream/package-info.java
diffstat 2 files changed, 39 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/util/stream/Stream.java	Fri Mar 22 16:01:01 2013 -0700
+++ b/src/share/classes/java/util/stream/Stream.java	Fri Mar 22 19:22:04 2013 -0400
@@ -44,7 +44,6 @@
 //   how reduce employs parallelism, more examples
 // - Role of stream flags in various operations, specifically ordering
 //   - Whether each op preserves encounter order
-// - collectUnordered
 // @@@ Specification to-do list @@@
 
 /**
@@ -75,7 +74,7 @@
      * <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
-     *                  embodying the criteria to apply to each element to determine if it should be included
+     *                  to apply to each element to determine if it should be included
      * @return the new stream
      */
     Stream<T> filter(Predicate<? super T> predicate);
@@ -145,7 +144,7 @@
      * <p>This implementation is likely to be less efficient than the other form of {@link #flatMap(FlatMapper)},
      * and is provided for convenience.
      * @param mapper A <a href="package-summary.html#NonInterference">non-interfering, stateless</a>
-     *               function to be applied to each element, resulting in a {@code Stream} of new values
+     *               function to be applied to each element which produces a {@code Stream} of new values
      * @return the new stream
      */
     <R> Stream<R> flatMap(Function<T, Stream<? extends R>> mapper);
@@ -262,25 +261,22 @@
      * 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 library chooses.  If the operation accesses
      * shared state, it is responsible for providing the required synchronization.
-     * @apiNote
-     * It may be desirable to perform the initial portion of a stream pipeline in parallel, but perform the
-     * final processing stage sequentially.  This can be accomplished by:
-     * <pre>
-     *     elements.parallelStream()
-     *             .filter(predicate)
-     *             .map(function)
-     *             .sequential()
-     *             .forEach(action);
-     * </pre>
-     * Here, the upstream stages (filtering and mapping) can be executed in parallel, but the results are
-     * collected and processed by the provided action sequentially in the initiating thread.
      *
      * @param consumer A <a href="package-summary.html#NonInterference">non-interfering</a>
      *                 action to perform on the elements
      */
     void forEach(Consumer<? super T> consumer);
 
-    /** @@@ Needs spec */
+    /**
+     * Perform an operation for each element of this stream, guaranteeing that each element
+     * is processed in encounter order for streams that have a defined encounter order.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">terminal operation</a>.
+     *
+     * @param consumer A <a href="package-summary.html#NonInterference">non-interfering</a>
+     *                 action to perform on the elements
+     * @see #forEach(Consumer)
+     */
     void forEachOrdered(Consumer<? super T> consumer);
 
     /**
@@ -557,11 +553,14 @@
      * of this stream using a {@code Collector} object to describe the reduction.  A {@code Collector}
      * encapsulates the functions used as arguments to {@link #collect(Supplier, BiConsumer, BiConsumer)},
      * allowing for reuse of collection strategies, and composition of collect operations such as multiple-level
-     * group-by.
+     * grouping or partitioning.
      *
      * <p>This is a <a href="package-summary.html#StreamOps">terminal operation</a>.
      *
-     * @@@ always non-concurrent / isolated
+     * When executed in parallel, multiple intermediate results may be instantiated, populated, and merged,
+     * so as to maintain isolation of mutable data structures.  Therefore, even when executed in parallel
+     * with non-thread-safe data structures (such as {@code ArrayList}), no additional synchronization is
+     * needed for a parallel reduction.
      *
      * @apiNote
      * The following will accumulate strings into an ArrayList:
@@ -591,7 +590,21 @@
      */
     <R> R collect(Collector<? super T, R> collector);
 
-    // @@@ Spec needed
+    /** Perform a <a href="package-summary.html#MutableReduction">mutable reduction</a> operation on the elements
+     * of this stream using a {@code Collector} object to describe the reduction, without regard to encounter order.
+     * If the provided {@code Collector} is concurrent, this implementation may invoke the function
+     * returned by {@link Collector#accumulator()} concurrently on the same result object.  In some cases,
+     * implementing a reduction by concurrently modifying a shared data structure may be more efficient than
+     * partitioning and merging.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">terminal operation</a>.
+     *
+     * @param collector The {@code Collector} describing the reduction
+     * @param <R> The type of the result
+     * @return The result of the reduction
+     * @see #collect(Supplier, BiConsumer, BiConsumer)
+     * @see Collectors
+     */
     <R> R collectUnordered(Collector<? super T, R> collector);
 
     /**
--- a/src/share/classes/java/util/stream/package-info.java	Fri Mar 22 16:01:01 2013 -0700
+++ b/src/share/classes/java/util/stream/package-info.java	Fri Mar 22 19:22:04 2013 -0400
@@ -206,14 +206,14 @@
  * (such as {@code List} or arrays) are intrinsically ordered, whereas others (such as {@code HashSet}) are
  * not.  Some intermediate operations may impose an encounter order on an otherwise unordered stream, such
  * as {@link java.util.stream.Stream#sorted()}.  Finally, some terminal operations may ignore encounter order,
- * such as {@code java.util.stream.Stream#forEach}, and others may have optimized implementations for the case
+ * such as {@link java.util.stream.Stream#forEach}, and others may have optimized implementations for the case
  * where there is no defined encounter order.
  *
  * <p>If a Stream is ordered, most operations are constrained to operate on the elements in their
- * encounter order.  If the source of a stream is a {@code List} containing {@code [1, 2, 3]}, then the
+ * encounter order; if the source of a stream is a {@code List} containing {@code [1, 2, 3]}, then the
  * result of executing {@code map(x -> x*2)} must be {@code [2, 4, 6]}.  However, if the source has no
  * defined encounter order, than any permutation of the values {@code [2, 4, 6]} would be a valid result.
- * However, many operations can still be efficiently parallelized even under such constraints.
+ * Many operations can still be efficiently parallelized even under such constraints.
  *
  * @@@ Interaction between ordering and concurrency
  *
@@ -230,15 +230,15 @@
  * specifically designed to handle concurrent modification, in which case their
  * {@code Spliterator} will report the {@code CONCURRENT} characteristic.)
  *
- * <p>Accordingly, lambdas passed to stream methods should never modify the stream's data
- * source.  A lambda (or other object implementing the appropriate functional interface)
+ * <p>Accordingly, lambda expressions (or other object implementing the appropriate functional interface)
+ * 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 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
  * results.
  *
- * <p>Further results may be nondeterministic or incorrect if the lambdas passed to
+ * <p>Further results may be nondeterministic or incorrect if the lambda expressions passed to
  * 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:
@@ -246,7 +246,7 @@
  *     Set<Integer> seen = Collections.synchronizedSet(new HashSet<>());
  *     stream.map(e -> { if (seen.add(e)) return 0; else return e; })...
  * </pre>
- * Stream pipelines with stateful lambdas may produce nondeterministic or incorrect results.
+ * Stream pipelines with stateful lambda expressions may produce nondeterministic or incorrect results.
  *
  * <h2>Side-effects</h2>
  *