830 * @param <U> The type of the result 831 * @param identity the identity value for the combiner function 832 * @param accumulator an <a href="package-summary.html#Associativity">associative</a>, 833 * <a href="package-summary.html#NonInterference">non-interfering</a>, 834 * <a href="package-summary.html#Statelessness">stateless</a> 835 * function for incorporating an additional element into a result 836 * @param combiner an <a href="package-summary.html#Associativity">associative</a>, 837 * <a href="package-summary.html#NonInterference">non-interfering</a>, 838 * <a href="package-summary.html#Statelessness">stateless</a> 839 * function for combining two values, which must be 840 * compatible with the accumulator function 841 * @return the result of the reduction 842 * @see #reduce(BinaryOperator) 843 * @see #reduce(Object, BinaryOperator) 844 */ 845 <U> U reduce(U identity, 846 BiFunction<U, ? super T, U> accumulator, 847 BinaryOperator<U> combiner); 848 849 /** 850 * Performs a <a href="package-summary.html#MutableReduction">mutable 851 * reduction</a> operation on the elements of this stream. A mutable 852 * reduction is one in which the reduced value is a mutable result container, 853 * such as an {@code ArrayList}, and elements are incorporated by updating 854 * the state of the result rather than by replacing the result. This 855 * produces a result equivalent to: 856 * <pre>{@code 857 * R result = supplier.get(); 858 * for (T element : this stream) 859 * accumulator.accept(result, element); 860 * return result; 861 * }</pre> 862 * 863 * <p>Like {@link #reduce(Object, BinaryOperator)}, {@code collect} operations 864 * can be parallelized without requiring additional synchronization. 865 * 866 * <p>This is a <a href="package-summary.html#StreamOps">terminal 867 * operation</a>. 868 * 869 * @apiNote There are many existing classes in the JDK whose signatures are | 830 * @param <U> The type of the result 831 * @param identity the identity value for the combiner function 832 * @param accumulator an <a href="package-summary.html#Associativity">associative</a>, 833 * <a href="package-summary.html#NonInterference">non-interfering</a>, 834 * <a href="package-summary.html#Statelessness">stateless</a> 835 * function for incorporating an additional element into a result 836 * @param combiner an <a href="package-summary.html#Associativity">associative</a>, 837 * <a href="package-summary.html#NonInterference">non-interfering</a>, 838 * <a href="package-summary.html#Statelessness">stateless</a> 839 * function for combining two values, which must be 840 * compatible with the accumulator function 841 * @return the result of the reduction 842 * @see #reduce(BinaryOperator) 843 * @see #reduce(Object, BinaryOperator) 844 */ 845 <U> U reduce(U identity, 846 BiFunction<U, ? super T, U> accumulator, 847 BinaryOperator<U> combiner); 848 849 /** 850 * Folds the elements of this stream using the provided seed object and 851 * accumulation function, going left to right. This is equivalent to: 852 * 853 * <pre>{@code 854 * U result = seed; 855 * for (T element : this stream) 856 * result = accumulator.apply(result, element) 857 * return result; 858 * } 859 * </pre> 860 * 861 * <p>This is a <a href="package-summary.html#StreamOps">terminal 862 * operation</a>. 863 * 864 * <p>This method cannot take all the advantages of parallel streams as it must 865 * process elements strictly left to right. If your accumulator function is 866 * associative and you can provide a combiner function, consider using 867 * {@link #reduce(Object, BiFunction, BinaryOperator)} method. 868 * 869 * @param <U> The type of the result 870 * @param seed the starting value 871 * @param accumulator a <a href="package-summary.html#NonInterference">non-interfering</a>, 872 * <a href="package-summary.html#Statelessness">stateless</a> 873 * function for incorporating an additional element into a result 874 * @return the result of the folding 875 * @see #foldRight(Object, BiFunction) 876 * @see #reduce(Object, BinaryOperator) 877 * @see #reduce(Object, BiFunction, BinaryOperator) 878 * @since 10 879 */ 880 default <U> U foldLeft(U seed, BiFunction<U, ? super T, U> accumulator) { 881 ReduceOps.FoldLeftWithSeedOp<U, ? super T> consumer = new ReduceOps.FoldLeftWithSeedOp<>(seed, accumulator); 882 forEachOrdered(consumer); 883 return consumer.get(); 884 } 885 886 /** 887 * Folds the elements of this stream using the provided accumulation 888 * function, going left to right. This is equivalent to: 889 * 890 * <pre>{@code 891 * boolean foundAny = false; 892 * T result = null; 893 * for (T element : this stream) { 894 * if (!foundAny) { 895 * foundAny = true; 896 * result = element; 897 * } 898 * else 899 * result = accumulator.apply(result, element); 900 * } 901 * return foundAny ? Optional.of(result) : Optional.empty(); 902 * } 903 * </pre> 904 * 905 * <p>This is a <a href="package-summary.html#StreamOps">terminal 906 * operation</a>. 907 * 908 * <p>This method cannot take all the advantages of parallel streams as it must 909 * process elements strictly left to right. If your accumulator function is 910 * associative, consider using {@link #reduce(BinaryOperator)} method. 911 * 912 * @param accumulator a <a href="package-summary.html#NonInterference">non-interfering</a>, 913 * <a href="package-summary.html#Statelessness">stateless</a> 914 * function for incorporating an additional element into a result 915 * @return the result of the folding 916 * @see #foldLeft(Object, BiFunction) 917 * @see #foldRight(BinaryOperator) 918 * @see #reduce(BinaryOperator) 919 * @since 10 920 */ 921 default Optional<T> foldLeft(BinaryOperator<T> accumulator) { 922 ReduceOps.FoldLeftOp<T> consumer = new ReduceOps.FoldLeftOp<>(accumulator); 923 forEachOrdered(consumer); 924 return consumer.get(); 925 } 926 927 /** 928 * Folds the elements of this stream using the provided seed object and 929 * accumulation function, going right to left. 930 * 931 * <p>This is a <a href="package-summary.html#StreamOps">terminal 932 * operation</a>. 933 * 934 * <p>As this method must process elements strictly right to left, it cannot 935 * start processing till all the previous stream stages complete. Also it 936 * requires intermediate memory to store the whole content of the stream as 937 * the stream natural order is left to right. If your accumulator function 938 * is associative and you can provide a combiner function, consider using 939 * {@link #reduce(Object, BiFunction, BinaryOperator)} method. 940 * 941 * @param <U> The type of the result 942 * @param seed the starting value 943 * @param accumulator a <a href="package-summary.html#NonInterference">non-interfering</a>, 944 * <a href="package-summary.html#Statelessness">stateless</a> 945 * function for incorporating an additional element into a result 946 * @return the result of the folding 947 * @see #foldLeft(Object, BiFunction) 948 * @see #reduce(Object, BinaryOperator) 949 * @see #reduce(Object, BiFunction, BinaryOperator) 950 * @since 10 951 */ 952 default <U> U foldRight(U seed, BiFunction<? super T, U, U> accumulator) { 953 Object[] array = toArray(); 954 U result = seed; 955 for(int idx = array.length - 1; idx >= 0; idx--) { 956 @SuppressWarnings("unchecked") 957 T t = (T) array[idx]; 958 result = accumulator.apply(t, result); 959 } 960 return result; 961 } 962 963 /** 964 * Folds the elements of this stream using the provided accumulation 965 * function, going right to left. 966 * 967 * <p>This is a <a href="package-summary.html#StreamOps">terminal 968 * operation</a>. 969 * 970 * <p> 971 * As this method must process elements strictly right to left, it cannot 972 * start processing till all the previous stream stages complete. Also it 973 * requires intermediate memory to store the whole content of the stream as 974 * the stream natural order is left to right. If your accumulator function 975 * is associative, consider using {@link #reduce(BinaryOperator)} method. 976 * 977 * @param accumulator a <a href="package-summary.html#NonInterference">non-interfering</a>, 978 * <a href="package-summary.html#Statelessness">stateless</a> 979 * function for incorporating an additional element into a result 980 * @return the result of the folding 981 * @see #foldRight(Object, BiFunction) 982 * @see #foldLeft(BinaryOperator) 983 * @see #reduce(BinaryOperator) 984 * @since 10 985 */ 986 default Optional<T> foldRight(BinaryOperator<T> accumulator) { 987 Object[] array = toArray(); 988 int idx = array.length; 989 if (idx == 0) return Optional.empty(); 990 @SuppressWarnings("unchecked") 991 T result = (T) array[--idx]; 992 while(idx > 0) { 993 @SuppressWarnings("unchecked") 994 T t = (T) array[--idx]; 995 result = accumulator.apply(t, result); 996 } 997 return Optional.of(result); 998 } 999 1000 /** 1001 * Performs a <a href="package-summary.html#MutableReduction">mutable 1002 * reduction</a> operation on the elements of this stream. A mutable 1003 * reduction is one in which the reduced value is a mutable result container, 1004 * such as an {@code ArrayList}, and elements are incorporated by updating 1005 * the state of the result rather than by replacing the result. This 1006 * produces a result equivalent to: 1007 * <pre>{@code 1008 * R result = supplier.get(); 1009 * for (T element : this stream) 1010 * accumulator.accept(result, element); 1011 * return result; 1012 * }</pre> 1013 * 1014 * <p>Like {@link #reduce(Object, BinaryOperator)}, {@code collect} operations 1015 * can be parallelized without requiring additional synchronization. 1016 * 1017 * <p>This is a <a href="package-summary.html#StreamOps">terminal 1018 * operation</a>. 1019 * 1020 * @apiNote There are many existing classes in the JDK whose signatures are |