--- /dev/null 2013-03-09 17:25:01.184291984 -0500 +++ new/src/share/classes/java/util/stream/IntermediateOp.java 2013-03-11 17:44:00.000000000 -0400 @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package java.util.stream; + +/** + * An operation in a stream pipeline that takes a stream as input and produces + * a stream, possibly of a different type, as output. An intermediate operation + * has an input type and an output type (and, an associated input shape and + * output shape). An intermediate operation also has a set of operation + * flags that describes how it transforms characteristics of the stream + * (such as sortedness or size; see {@link StreamOpFlag}). + * + *
Intermediate operations are implemented in terms of sink transforms + * ; given a {@code Sink} for the output type of the operation, produce a + * {@code Sink} for the input type of the operation, which, when fed with + * values, has the effect of implementing the desired operation on the input + * values and feeding them to the output sink. + * + *
Some intermediate operations are stateful. This means that the + * sinks they produce as a result of the above wrapping may maintain state from + * processing earlier elements. Stateful intermediate operations must implement + * the {@link StatefulOp} interface. Statefulness has an effect on how the + * operation can be parallelized. Stateless operations parallelize trivially + * because they are homomorphisms under concatenation: + * + *
+ * statelessOp(a || b) = statelessOp(a) || statelessOp(b) + *+ * + * where {@code ||} denotes concatenation. Stateful operations may still be + * parallelizable, but are not amenable to the automatic parallelization of + * stateless operations. Accordingly, a stateful operation must provide its own + * parallel execution implementation + * ({@link StatefulOp#evaluateParallel(PipelineHelper)}). + * + * @apiNote + * As an example, consider the stream pipeline: + *
+ * int oldestBob = people.stream(). + * filter(p -> p.getFirstName.equals("Bob")). + * map(p -> p.getAge()).max(); + *+ * + *
This pipeline has two intermediate operations, filter and map. The + * filtering operation has input and output types of {@code Person} (with input + * and output shape of {@code REFERENCE}), and the mapping operation has an + * input type of {@code Person} and an output type of {@code Integer} (with + * shape {@code INT_VALUE}.) When we construct a sink chain, the mapping + * operation will be asked to transform a {@code Sink.OfInt} which computes the + * maximum value into a {@code Sink} which accepts {@code Person} objects, and + * whose behavior is to take the supplied {@code Person}, call {@code getAge()} + * on it, and pass the resulting value to the downstream sink. This sink + * transform might be implement as: + * + *
+ * new Sink.ChainedReference(sink) { + * public void accept(U u) { + * downstream.accept(mappingFunction.applyAsInt(u)); + * } + * } + *+ * + * @param
The implementation may use the {@code flags} parameter to optimize the
+ * sink wrapping. For example, if the input is already {@code DISTINCT},
+ * the implementation for the {@code Stream#distinct()} method could just
+ * return the sink it was passed.
+ *
+ * @param flags The combined stream and operation flags up to, but not
+ * including, this operation.
+ * @param sink elements will be sent to this sink after the processing.
+ * @return a sink which will accept elements and perform the operation upon
+ * each element, passing the results (if any) to the provided
+ * {@code Sink}.
+ */
+ Sink