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.

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);
}
}
```