Java 8 Reduce

Reduce is a functional programming technique that combines values and returns a value. Find out how to use the stream reduce function in java 8.

Getting started

Reduce, otherwise known as fold, aggregate or collapse, is a java 8 stream method that applies a function to elements of the stream in turn returning a reduced value. Common examples include finding the sum, min, max, average, and string concatenation. Let's walk through what reduce is at its basics.

First look at reduce

The following code snippet will sum the values of the stream.

@Test
public void reduce_java8_lambda() {

    List<Integer> myList = Arrays.asList(1, 2, 3, 4, 5);

    double sum = myList.stream().reduce(0, (a, b) -> a + b);

    // or myList.stream().reduce(0, Integer::sum);

    System.out.println(sum); //15.0
}

The first element passed to the reduce is 0. 0 represents the identity or the initial value of the reduction and the default result if there is no elements within the stream. In this instance, the identity must be of type Integer due to myList containing integers. If the identity started with 2, the sum with be 17.0.

The second parameter is the lambda expression representing the accumulator or function (a, b) -> a + b. Breaking down this stateless function, "a" represents the partial results of the reduction or the sum of all the processed numbers. The second part, "b", is the next integer to process or add.

Let's look at what is being processed through the accumulator in a table format.

 abreturn value
first call011
second call123
third call336
fourth call6410
fifth call10515

BinaryOperator in place of lambda

In the instance you wanted to reuse the reduction function across many locations, you could refactor the example above to use the BinaryOperator. A BinaryOperator is a @FunctionalInterface and will execute an operation on two values.

@Test
public void reduce_java8_binaryOperator() {

    List<Integer> myList = Arrays.asList(1, 2, 3, 4, 5);

    BinaryOperator<Integer> sum3 = (a, b) -> a + b;
    
    double sum = myList.stream().reduce(2, sum3);

    System.out.println(sum); // 17
}

Convenience methods

Java 8 introduced a special type of stream for handling their respective data types. IntStream, DoubleStream and LongStream come along with reduction convenience methods. Rewriting the example above will look a little different but will perform the same behavior.

Converting the list to a stream then mapping each value to a primitive int will return an IntStream. Calling the sum function will reduce the stream returning 15.

@Test
public void reduce_java8_a() {

    List<Integer> myList = Arrays.asList(1, 2, 3, 4, 5);

    int sum = myList.stream().mapToInt(Integer::intValue).sum();

    System.out.println(sum);
}

This stream reduce examples shown there is multitude of ways to write reduction operation and it gives you a break from a typical imperative way to code. Thanks for joining in today's level up, have a great day!