--- old/src/java.base/share/classes/java/util/stream/DoubleStream.java 2017-08-13 19:17:27.637546100 +0600 +++ new/src/java.base/share/classes/java/util/stream/DoubleStream.java 2017-08-13 19:17:27.433520200 +0600 @@ -547,6 +547,147 @@ OptionalDouble reduce(DoubleBinaryOperator op); /** + * Folds the elements of this stream using the provided {@code seed} value and + * accumulation function, going left to right. This is equivalent to: + * + *
{@code
+     *     double result = seed;
+     *     for (double element : this stream)
+     *         result = accumulator.apply(result, element)
+     *     return result;
+     * }
+     * 
+ * + *

This is a terminal + * operation. + * + *

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 {@code seed} value has identity properties, + * consider using {@link #reduce(double, DoubleBinaryOperator)} method. + * + * @param seed the starting value + * @param accumulator a non-interfering, + * stateless + * function for incorporating an additional element into a result + * @return the result of the folding + * @see #reduce(double, DoubleBinaryOperator) + * @see #foldLeft(DoubleBinaryOperator) + * @since 10 + */ + default double foldLeft(double seed, DoubleBinaryOperator accumulator) { + ReduceOps.DoubleFoldLeftOp op = new ReduceOps.DoubleFoldLeftOp(accumulator); + op.accept(seed); + forEachOrdered(op); + return op.getAsDouble(); + } + + /** + * Folds the elements of this stream using the provided accumulation + * function, going left to right. This is equivalent to: + * + *

{@code
+     *     boolean foundAny = false;
+     *     double result = 0;
+     *     for (double element : this stream) {
+     *         if (!foundAny) {
+     *             foundAny = true;
+     *             result = element;
+     *         }
+     *         else
+     *             result = accumulator.apply(result, element);
+     *     }
+     *     return foundAny ? OptionalDouble.of(result) : OptionalDouble.empty();
+     * }
+     * 
+ * + *

This is a terminal + * operation. + * + *

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(DoubleBinaryOperator)} method. + * + * @param accumulator a non-interfering, + * stateless + * function for incorporating an additional element into a result + * @return the result of the folding + * @see #foldLeft(double, DoubleBinaryOperator) + * @see #reduce(DoubleBinaryOperator) + * @since 10 + */ + default OptionalDouble foldLeft(DoubleBinaryOperator accumulator) { + ReduceOps.DoubleFoldLeftOp op = new ReduceOps.DoubleFoldLeftOp(accumulator); + forEachOrdered(op); + return op.get(); + } + + /** + * Folds the elements of this stream using the provided {@code seed} value and + * accumulation function, going right to left. + * + *

This is a terminal + * operation. + * + *

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 {@code seed} value has identity properties, + * consider using {@link #reduce(double, DoubleBinaryOperator)} method. + * + * @param seed the starting value + * @param accumulator a non-interfering, + * stateless + * function for incorporating an additional element into a result + * @return the result of the folding + * @see #foldLeft(double, DoubleBinaryOperator) + * @see #reduce(double, DoubleBinaryOperator) + * @since 10 + */ + default double foldRight(double seed, DoubleBinaryOperator accumulator) { + double[] array = toArray(); + double result = seed; + for(int idx = array.length - 1; idx >= 0; idx--) { + result = accumulator.applyAsDouble(array[idx], result); + } + return result; + } + + /** + * Folds the elements of this stream using the provided accumulation + * function, going right to left. + * + *

This is a terminal + * operation. + * + *

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(DoubleBinaryOperator)} method. + * + * @param accumulator a non-interfering, + * stateless + * function for incorporating an additional element into a result + * @return the result of the folding + * @see #foldLeft(double, DoubleBinaryOperator) + * @see #reduce(double, DoubleBinaryOperator) + * @since 10 + */ + default OptionalDouble foldRight(DoubleBinaryOperator accumulator) { + double[] array = toArray(); + int idx = array.length; + if (idx == 0) return OptionalDouble.empty(); + double result = array[--idx]; + while(idx > 0) { + double t = array[--idx]; + result = accumulator.applyAsDouble(t, result); + } + return OptionalDouble.of(result); + } + + /** * Performs a mutable * reduction operation on the elements of this stream. A mutable * reduction is one in which the reduced value is a mutable result container,