OpenJDK / lambda / lambda / jdk
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> *