< prev index next >
src/java.base/share/classes/java/util/stream/Stream.java
Print this page
@@ -845,10 +845,161 @@
<U> U reduce(U identity,
BiFunction<U, ? super T, U> accumulator,
BinaryOperator<U> combiner);
/**
+ * Folds the elements of this stream using the provided seed object and
+ * accumulation function, going left to right. This is equivalent to:
+ *
+ * <pre>{@code
+ * U result = seed;
+ * for (T element : this stream)
+ * result = accumulator.apply(result, element)
+ * return result;
+ * }
+ * </pre>
+ *
+ * <p>This is a <a href="package-summary.html#StreamOps">terminal
+ * operation</a>.
+ *
+ * <p>This method cannot take all the advantages of parallel streams as it must
+ * process elements strictly left to right. If your accumulator function is
+ * associative and you can provide a combiner function, consider using
+ * {@link #reduce(Object, BiFunction, BinaryOperator)} method.
+ *
+ * @param <U> The type of the result
+ * @param seed the starting value
+ * @param accumulator 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
+ * @return the result of the folding
+ * @see #foldRight(Object, BiFunction)
+ * @see #reduce(Object, BinaryOperator)
+ * @see #reduce(Object, BiFunction, BinaryOperator)
+ * @since 10
+ */
+ default <U> U foldLeft(U seed, BiFunction<U, ? super T, U> accumulator) {
+ ReduceOps.FoldLeftWithSeedOp<U, ? super T> consumer = new ReduceOps.FoldLeftWithSeedOp<>(seed, accumulator);
+ forEachOrdered(consumer);
+ return consumer.get();
+ }
+
+ /**
+ * Folds the elements of this stream using the provided accumulation
+ * function, going left to right. This is equivalent to:
+ *
+ * <pre>{@code
+ * boolean foundAny = false;
+ * T result = null;
+ * for (T element : this stream) {
+ * if (!foundAny) {
+ * foundAny = true;
+ * result = element;
+ * }
+ * else
+ * result = accumulator.apply(result, element);
+ * }
+ * return foundAny ? Optional.of(result) : Optional.empty();
+ * }
+ * </pre>
+ *
+ * <p>This is a <a href="package-summary.html#StreamOps">terminal
+ * operation</a>.
+ *
+ * <p>This method cannot take all the advantages of parallel streams as it must
+ * process elements strictly left to right. If your accumulator function is
+ * associative, consider using {@link #reduce(BinaryOperator)} method.
+ *
+ * @param accumulator 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
+ * @return the result of the folding
+ * @see #foldLeft(Object, BiFunction)
+ * @see #foldRight(BinaryOperator)
+ * @see #reduce(BinaryOperator)
+ * @since 10
+ */
+ default Optional<T> foldLeft(BinaryOperator<T> accumulator) {
+ ReduceOps.FoldLeftOp<T> consumer = new ReduceOps.FoldLeftOp<>(accumulator);
+ forEachOrdered(consumer);
+ return consumer.get();
+ }
+
+ /**
+ * Folds the elements of this stream using the provided seed object and
+ * accumulation function, going right to left.
+ *
+ * <p>This is a <a href="package-summary.html#StreamOps">terminal
+ * operation</a>.
+ *
+ * <p>As this method must process elements strictly right to left, it cannot
+ * start processing till all the previous stream stages complete. Also it
+ * requires intermediate memory to store the whole content of the stream as
+ * the stream natural order is left to right. If your accumulator function
+ * is associative and you can provide a combiner function, consider using
+ * {@link #reduce(Object, BiFunction, BinaryOperator)} method.
+ *
+ * @param <U> The type of the result
+ * @param seed the starting value
+ * @param accumulator 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
+ * @return the result of the folding
+ * @see #foldLeft(Object, BiFunction)
+ * @see #reduce(Object, BinaryOperator)
+ * @see #reduce(Object, BiFunction, BinaryOperator)
+ * @since 10
+ */
+ default <U> U foldRight(U seed, BiFunction<? super T, U, U> accumulator) {
+ Object[] array = toArray();
+ U result = seed;
+ for(int idx = array.length - 1; idx >= 0; idx--) {
+ @SuppressWarnings("unchecked")
+ T t = (T) array[idx];
+ result = accumulator.apply(t, result);
+ }
+ return result;
+ }
+
+ /**
+ * Folds the elements of this stream using the provided accumulation
+ * function, going right to left.
+ *
+ * <p>This is a <a href="package-summary.html#StreamOps">terminal
+ * operation</a>.
+ *
+ * <p>
+ * As this method must process elements strictly right to left, it cannot
+ * start processing till all the previous stream stages complete. Also it
+ * requires intermediate memory to store the whole content of the stream as
+ * the stream natural order is left to right. If your accumulator function
+ * is associative, consider using {@link #reduce(BinaryOperator)} method.
+ *
+ * @param accumulator 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
+ * @return the result of the folding
+ * @see #foldRight(Object, BiFunction)
+ * @see #foldLeft(BinaryOperator)
+ * @see #reduce(BinaryOperator)
+ * @since 10
+ */
+ default Optional<T> foldRight(BinaryOperator<T> accumulator) {
+ Object[] array = toArray();
+ int idx = array.length;
+ if (idx == 0) return Optional.empty();
+ @SuppressWarnings("unchecked")
+ T result = (T) array[--idx];
+ while(idx > 0) {
+ @SuppressWarnings("unchecked")
+ T t = (T) array[--idx];
+ result = accumulator.apply(t, result);
+ }
+ return Optional.of(result);
+ }
+
+ /**
* Performs a <a href="package-summary.html#MutableReduction">mutable
* reduction</a> operation on the elements of this stream. A mutable
* reduction is one in which the reduced value is a mutable result container,
* such as an {@code ArrayList}, and elements are incorporated by updating
* the state of the result rather than by replacing the result. This
< prev index next >