### Java 8 - Streams - reduce()

Greetings!

Stream API provides several terminal operations for common tasks like count, min, max, sum and average.  These operations return a single value and do specific task. Stream.collect() operation is also a terminal operations but it return a Collection.
reduce() is a more-general purpose operations which can be used to combine the content of stream.

• These terminal operations are called reduction operations.

### Stream.reduce()

This method mainly has two forms.

• With initial value.
• Without initial value.
``````
T reduce(T identity, BinaryOperator<T> accumulator);

Optional<T> reduce(BinaryOperator<T> accumulator);
```
```

reduce uses BinaryOperator (which extends BiFunction) functional interface which has the form below.
``````
R apply(T t, U u);
```
```

### How Does It Work

Let's consider below sum operation.
``````
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int result = 0;
for (Integer number : numbers) {
result = result + number;
}
System.out.println(result);
```
```

We have a result variable with an initial value and during iteration we add current iteration value to result and assign the calculated value back to result.
Now, this is a reduce operation which fulfills reduce() methods contract.
So, this same operation can be written using reduce like this;
``````
int result8 = numbers.stream().reduce(0, (a, b) -> a + b);
System.out.println(result8);
```
```
a - result, b - iteration value
When we are reducing a Collection using iteration which depends on the last calculated value, it is good time to use reduce().

More examples;
``````
import java.util.Arrays;
import java.util.List;

public class ReduceApp {

public static void main(String[] args) {
// Java 7
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int result = 0;
for (Integer number : numbers) {
result = result + number;
}
System.out.println(result);

// Java 8
int result8 = numbers.stream().reduce(0, (a, b) -> a + b);
System.out.println(result8);

int multiplication = numbers.stream().reduce(1, (a, b) -> a * b);
System.out.println(multiplication);

int evenPow = numbers.stream().filter(i -> i % 2 == 0).reduce(0, (a, b) -> a + b * b);
System.out.println(evenPow);

List<String> target = Arrays.asList("H", "e", "l", "l", "o");
String reversed = target.stream().reduce("", (a, b) -> b + a);
System.out.println(reversed);
}

}
```
```