Java 8 Stream.reduce() examples

In Java 8, the Stream.reduce() combine elements of a stream and produces a single value.

A simple sum operation using a for loop.


  int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  int sum = 0;
  for (int i : numbers) {
      sum += i;
  }

  System.out.println("sum : " + sum); // 55

The equivalent in Stream.reduce()


  int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

  // 1st argument, init value = 0
  int sum = Arrays.stream(numbers).reduce(0, (a, b) -> a + b);

  System.out.println("sum : " + sum); // 55

or method reference with Integer::sum


int sum = Arrays.stream(numbers).reduce(0, Integer::sum); // 55
Integer.java

    /**
     * Adds two integers together as per the + operator.
     *
     * @param a the first operand
     * @param b the second operand
     * @return the sum of {@code a} and {@code b}
     * @see java.util.function.BinaryOperator
     * @since 1.8
     */
    public static int sum(int a, int b) {
        return a + b;
    }

1. Method Signature

1.1 Review the Stream.reduce() method signature:

Stream.java

T reduce(T identity, BinaryOperator<T> accumulator);
IntStream.java

int reduce(int identity, IntBinaryOperator op);
LongStream.java

long reduce(int identity, LongBinaryOperator op);
  • identity = default or initial value.
  • BinaryOperator = functional interface, take two values and produces a new value.

1.2 if the identity argument is missing, there is no default or initial value, and it returns an optional.

Stream.java

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

2. More Examples

2.1 Math operations.


int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

int sum = Arrays.stream(numbers).reduce(0, (a, b) -> a + b);    // 55
int sum2 = Arrays.stream(numbers).reduce(0, Integer::sum);      // 55

int sum3 = Arrays.stream(numbers).reduce(0, (a, b) -> a - b);   // -55
int sum4 = Arrays.stream(numbers).reduce(0, (a, b) -> a * b);   // 0, initial is 0, 0 * whatever = 0
int sum5 = Arrays.stream(numbers).reduce(0, (a, b) -> a / b);   // 0

2.2 Max and Min.


int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

int max = Arrays.stream(numbers).reduce(0, (a, b) -> a > b ? a : b);  // 10
int max1 = Arrays.stream(numbers).reduce(0, Integer::max);            // 10

int min = Arrays.stream(numbers).reduce(0, (a, b) -> a < b ? a : b);  // 0
int min1 = Arrays.stream(numbers).reduce(0, Integer::min);            // 0

2.3 Join String.


  String[] strings = {"a", "b", "c", "d", "e"};

  // |a|b|c|d|e , the initial | join is not what we want
  String reduce = Arrays.stream(strings).reduce("", (a, b) -> a + "|" + b);

  // a|b|c|d|e, filter the initial "" empty string
  String reduce2 = Arrays.stream(strings).reduce("", (a, b) -> {
      if (!"".equals(a)) {
          return a + "|" + b;
      } else {
          return b;
      }
  });

  // a|b|c|d|e , better uses the Java 8 String.join :)
  String join = String.join("|", strings);

3. Map & Reduce

A simple map and reduce example to sum BigDecimal from a list of invoices.

JavaReduce.java

package com.mkyong;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;
import java.util.List;

public class JavaReduce {

    public static void main(String[] args) {

        List<Invoice> invoices = Arrays.asList(
                new Invoice("A01", BigDecimal.valueOf(9.99), BigDecimal.valueOf(1)),
                new Invoice("A02", BigDecimal.valueOf(19.99), BigDecimal.valueOf(1.5)),
                new Invoice("A03", BigDecimal.valueOf(4.99), BigDecimal.valueOf(2))
        );

        BigDecimal sum = invoices.stream()
                .map(x -> x.getQty().multiply(x.getPrice()))    // map
                .reduce(BigDecimal.ZERO, BigDecimal::add);      // reduce

        System.out.println(sum);    // 49.955
        System.out.println(sum.setScale(2, RoundingMode.HALF_UP));  // 49.96

    }

}

class Invoice {

    String invoiceNo;
    BigDecimal price;
    BigDecimal qty;

    // getters, stters n constructor
}

Output


49.955
49.96

References

6 comments on “Java 8 Stream.reduce() examples

  1. Hi – thanks for this introduction to reduce() ! Note: some of the examples assume positive array values. This would be a more general approach:

    int[] all_ints = {-20, -5, 0, 5, 20};
    int max = Arrays.stream(all_ints).reduce(all_ints[0], Integer::max);

    Reply
  2. Hi, quick query for 3rd example. Map and reduce. what if any of the BigDecimal values in the addition is null? How to handle error in same line?

    Reply
  3. on 2.3 Join String.

    Arrays.stream(….)
       .collect(Collectors.joining(“|”));

    Reply
  4. Hi!
    Here
    long reduce(int identity, LongBinaryOperator op);
    the identity is not type int, but long.

    Reply
  5. U have a very sophisticated, simple and efficient way to explain things & for that I salute u ^^

    Reply

Leave a Comment

Your email address will not be published. Required fields are marked *