**Generic Reduction Operation**

The stream API generalizes the reduction operation concept by providing the reduce( ) method. By using reduce( ), you can return a value from a stream based on any arbitrary criteria. By definition, all reduction operations are terminal operations. Stream defines three versions of reduce( ). The two we will use first are :

The first form returns an object of type Optional, which contains the result. The second form returns an object of type T (which is the element type of the stream). In both forms, accumulator is a function that operates on two values and produces a result. In the second form, identityVal is a value such that an accumulator operation involving identityVal and any element of the stream yields that element, unchanged. BinaryOperator is a functional interface declared in java.util.function that extends the BiFunction functional interface. BiFunction declares one abstract method called apply().

Here, R specifies the result type, T is the type of the first operand, and U is the type of second operand. Thus, apply( ) applies a function to its two operands (t and u) and returns the result. When BinaryOperator extends BiFunction, it specifies the same type for all the type parameters. Thus, as it relates to BinaryOperator, apply( ) looks like following:

Furthermore, as it relates to reduce( ), t will contain the previous result and u will contain the next element. In its first invocation, t will contain either the identity value or the first element, depending on which version of reduce( ) is used.

**First version reduce() example**

The reduce() method uses the lambda expression to produce a product of two values. In this case, because the stream contains Integer values, the Integer objects are automatically unboxed for the multiplication and reboxed to return the result. The two values represent the current value of the running result and the next element in the stream. The final result is returned in an object of type Optional. The value is obtained by calling get( ) on the returned object.

**Second version reduce() example**

The identity value is explicitly specified, which for addition is 5. Notice that the result is returned as an object of the element type, which is Integer in this case. Although simple reduction operations such as multiplication are useful for examples, reductions are not limited in this regard. The following example shows how to obtain the total value of less than 100 values:

import java.util.ArrayList; import java.util.Optional; public class Javaapp { public static void main(String[] args) { ArrayList<Integer> arylist = new ArrayList<Integer>(); arylist.add(60); arylist.add(110); arylist.add(40); arylist.add(120); arylist.add(90); Optional get1 = arylist.stream().reduce((a,b)->a*b); int get2 = arylist.stream().reduce(0,(a,b)->a+b); int get3 = arylist.stream().reduce(0, (a, b) -> { if (b > 100) { return a; } else { return a + b; } }); System.out.println("get1-> "+get1.get()); System.out.println("get2-> "+get2); System.out.println("get3-> "+get3); } }