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