Main Tutorials

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

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
6 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
Luciana
3 years ago

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

Phil
1 year ago

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

SSD
2 years ago

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?

Josimar Amilcar Fernandes Andrade
2 years ago

on 2.3 Join String.

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

ma_igor
3 years ago

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