530 * }</pre> 531 * 532 * but is not constrained to execute sequentially. 533 * 534 * <p>The {@code accumulator} function must be an 535 * <a href="package-summary.html#Associativity">associative</a> function. 536 * 537 * <p>This is a <a href="package-summary.html#StreamOps">terminal 538 * operation</a>. 539 * 540 * @param op an <a href="package-summary.html#Associativity">associative</a>, 541 * <a href="package-summary.html#NonInterference">non-interfering</a>, 542 * <a href="package-summary.html#Statelessness">stateless</a> 543 * function for combining two values 544 * @return the result of the reduction 545 * @see #reduce(double, DoubleBinaryOperator) 546 */ 547 OptionalDouble reduce(DoubleBinaryOperator op); 548 549 /** 550 * Performs a <a href="package-summary.html#MutableReduction">mutable 551 * reduction</a> operation on the elements of this stream. A mutable 552 * reduction is one in which the reduced value is a mutable result container, 553 * such as an {@code ArrayList}, and elements are incorporated by updating 554 * the state of the result rather than by replacing the result. This 555 * produces a result equivalent to: 556 * <pre>{@code 557 * R result = supplier.get(); 558 * for (double element : this stream) 559 * accumulator.accept(result, element); 560 * return result; 561 * }</pre> 562 * 563 * <p>Like {@link #reduce(double, DoubleBinaryOperator)}, {@code collect} 564 * operations can be parallelized without requiring additional 565 * synchronization. 566 * 567 * <p>This is a <a href="package-summary.html#StreamOps">terminal 568 * operation</a>. 569 * | 530 * }</pre> 531 * 532 * but is not constrained to execute sequentially. 533 * 534 * <p>The {@code accumulator} function must be an 535 * <a href="package-summary.html#Associativity">associative</a> function. 536 * 537 * <p>This is a <a href="package-summary.html#StreamOps">terminal 538 * operation</a>. 539 * 540 * @param op an <a href="package-summary.html#Associativity">associative</a>, 541 * <a href="package-summary.html#NonInterference">non-interfering</a>, 542 * <a href="package-summary.html#Statelessness">stateless</a> 543 * function for combining two values 544 * @return the result of the reduction 545 * @see #reduce(double, DoubleBinaryOperator) 546 */ 547 OptionalDouble reduce(DoubleBinaryOperator op); 548 549 /** 550 * Folds the elements of this stream using the provided {@code seed} value and 551 * accumulation function, going left to right. This is equivalent to: 552 * 553 * <pre>{@code 554 * double result = seed; 555 * for (double element : this stream) 556 * result = accumulator.apply(result, element) 557 * return result; 558 * } 559 * </pre> 560 * 561 * <p>This is a <a href="package-summary.html#StreamOps">terminal 562 * operation</a>. 563 * 564 * <p>This method cannot take all the advantages of parallel streams as it must 565 * process elements strictly left to right. If your accumulator function 566 * is associative, and {@code seed} value has identity properties, 567 * consider using {@link #reduce(double, DoubleBinaryOperator)} method. 568 * 569 * @param seed the starting value 570 * @param accumulator a <a href="package-summary.html#NonInterference">non-interfering</a>, 571 * <a href="package-summary.html#Statelessness">stateless</a> 572 * function for incorporating an additional element into a result 573 * @return the result of the folding 574 * @see #reduce(double, DoubleBinaryOperator) 575 * @see #foldLeft(DoubleBinaryOperator) 576 * @since 10 577 */ 578 default double foldLeft(double seed, DoubleBinaryOperator accumulator) { 579 ReduceOps.DoubleFoldLeftOp op = new ReduceOps.DoubleFoldLeftOp(accumulator); 580 op.accept(seed); 581 forEachOrdered(op); 582 return op.getAsDouble(); 583 } 584 585 /** 586 * Folds the elements of this stream using the provided accumulation 587 * function, going left to right. This is equivalent to: 588 * 589 * <pre>{@code 590 * boolean foundAny = false; 591 * double result = 0; 592 * for (double element : this stream) { 593 * if (!foundAny) { 594 * foundAny = true; 595 * result = element; 596 * } 597 * else 598 * result = accumulator.apply(result, element); 599 * } 600 * return foundAny ? OptionalDouble.of(result) : OptionalDouble.empty(); 601 * } 602 * </pre> 603 * 604 * <p>This is a <a href="package-summary.html#StreamOps">terminal 605 * operation</a>. 606 * 607 * <p>This method cannot take all the advantages of parallel streams as it must 608 * process elements strictly left to right. If your accumulator function is 609 * associative, consider using {@link #reduce(DoubleBinaryOperator)} method. 610 * 611 * @param accumulator a <a href="package-summary.html#NonInterference">non-interfering</a>, 612 * <a href="package-summary.html#Statelessness">stateless</a> 613 * function for incorporating an additional element into a result 614 * @return the result of the folding 615 * @see #foldLeft(double, DoubleBinaryOperator) 616 * @see #reduce(DoubleBinaryOperator) 617 * @since 10 618 */ 619 default OptionalDouble foldLeft(DoubleBinaryOperator accumulator) { 620 ReduceOps.DoubleFoldLeftOp op = new ReduceOps.DoubleFoldLeftOp(accumulator); 621 forEachOrdered(op); 622 return op.get(); 623 } 624 625 /** 626 * Folds the elements of this stream using the provided {@code seed} value and 627 * accumulation function, going right to left. 628 * 629 * <p>This is a <a href="package-summary.html#StreamOps">terminal 630 * operation</a>. 631 * 632 * <p>As this method must process elements strictly right to left, it cannot 633 * start processing till all the previous stream stages complete. Also it 634 * requires intermediate memory to store the whole content of the stream as 635 * the stream natural order is left to right. If your accumulator function 636 * is associative, and {@code seed} value has identity properties, 637 * consider using {@link #reduce(double, DoubleBinaryOperator)} method. 638 * 639 * @param seed the starting value 640 * @param accumulator a <a href="package-summary.html#NonInterference">non-interfering</a>, 641 * <a href="package-summary.html#Statelessness">stateless</a> 642 * function for incorporating an additional element into a result 643 * @return the result of the folding 644 * @see #foldLeft(double, DoubleBinaryOperator) 645 * @see #reduce(double, DoubleBinaryOperator) 646 * @since 10 647 */ 648 default double foldRight(double seed, DoubleBinaryOperator accumulator) { 649 double[] array = toArray(); 650 double result = seed; 651 for(int idx = array.length - 1; idx >= 0; idx--) { 652 result = accumulator.applyAsDouble(array[idx], result); 653 } 654 return result; 655 } 656 657 /** 658 * Folds the elements of this stream using the provided accumulation 659 * function, going right to left. 660 * 661 * <p>This is a <a href="package-summary.html#StreamOps">terminal 662 * operation</a>. 663 * 664 * <p>As this method must process elements strictly right to left, it cannot 665 * start processing till all the previous stream stages complete. Also it 666 * requires intermediate memory to store the whole content of the stream as 667 * the stream natural order is left to right. If your accumulator function 668 * is associative, consider using {@link #reduce(DoubleBinaryOperator)} method. 669 * 670 * @param accumulator a <a href="package-summary.html#NonInterference">non-interfering</a>, 671 * <a href="package-summary.html#Statelessness">stateless</a> 672 * function for incorporating an additional element into a result 673 * @return the result of the folding 674 * @see #foldLeft(double, DoubleBinaryOperator) 675 * @see #reduce(double, DoubleBinaryOperator) 676 * @since 10 677 */ 678 default OptionalDouble foldRight(DoubleBinaryOperator accumulator) { 679 double[] array = toArray(); 680 int idx = array.length; 681 if (idx == 0) return OptionalDouble.empty(); 682 double result = array[--idx]; 683 while(idx > 0) { 684 double t = array[--idx]; 685 result = accumulator.applyAsDouble(t, result); 686 } 687 return OptionalDouble.of(result); 688 } 689 690 /** 691 * Performs a <a href="package-summary.html#MutableReduction">mutable 692 * reduction</a> operation on the elements of this stream. A mutable 693 * reduction is one in which the reduced value is a mutable result container, 694 * such as an {@code ArrayList}, and elements are incorporated by updating 695 * the state of the result rather than by replacing the result. This 696 * produces a result equivalent to: 697 * <pre>{@code 698 * R result = supplier.get(); 699 * for (double element : this stream) 700 * accumulator.accept(result, element); 701 * return result; 702 * }</pre> 703 * 704 * <p>Like {@link #reduce(double, DoubleBinaryOperator)}, {@code collect} 705 * operations can be parallelized without requiring additional 706 * synchronization. 707 * 708 * <p>This is a <a href="package-summary.html#StreamOps">terminal 709 * operation</a>. 710 * |