Skip to main content

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

}





Comments