Streams – reduce() operation

Stream reduce() belong to reduction stream operations in Java. We have already covered a set of predefined reduction operations, such as average(), sum(), min(), max(), and count(). Reduction stream operations allow us to produce one single result from a sequence of elements by applying a specific operation to the elements in the sequence.

Java Stream reduce() is a method for generating custom reduction operations on a stream. Unlike min(), max(), etc., we have the freedom to explicitly specify how the data that made it through the stream should be reduced.

Syntax

T reduce(T identity, BinaryOperator<T> accumulator);

Here:

  • identity – an element that is the initial value of the reduction operation and the default result if the stream is empty
  • accumulator – It’s a BinaryOperator. It represents a function that takes two parameters, the first is the result of a previous reduction operation, and the second is the next element in the stream.

How does the reduce() function works?

Let’s see one example:

A program that multiplies all the elements from the stream.

class Test {

  public static void main(String[] args) {
    List<Integer> numbers = new ArrayList<>(Arrays.asList(3, 5, 7, 9));

    int result = numbers.stream()
            .reduce(1, (num1, num2) -> num1 * num2);

    System.out.println("The result is: " + result);
  }
}

Output: The result is: 945

Let’s see how it works, we have a stream of [3, 5, 7, 9] :

Now, we set the identity/the initial value to be 1. When the first element arrives, which is number 3, it represents the second parameter of the accumulator function, and the first parameter is number 1. Then the multiplication is performed, and the result gets placed in identity.

Now the second element arrives, which is number 5, and it gets multiplied with the identity value, which is the result from the previous operation, and we get 5 * 3 = 15. So, now the identity has a value of 15. After that, we get the third parameter 7 and it gets multiplied by 15, which is the current identity value, and we get 105, which gets placed as the new value of identity.

Now, we get the fourth and the final element from the stream, which is number 9, and it gets multiplied by 105, and we get the result 945, which is the final result of the reduce() operation.

Examples

Example 1

A program that displays the longest name:

class Test {

  public static void main(String[] args) {
    List<String> names = new ArrayList<>(Arrays.asList("Megan", "John", "Melissa", "Alex", "Tom", "Jonathan", "Steve"));

    String longestName = names.stream()
            .reduce("", (str1, str2) -> str1.length() > str2.length() ? str1 : str2);

    System.out.println("The longest name is: " + longestName);
  }
}

Output: The longest name is: Jonathan

Example 2

A program that concatenates all strings from the stream.

class Test {
  public static void main(String[] args) {
    List<String> words = new ArrayList<>(Arrays.asList("This", "is", "coding", "blog", "from", "alegru"));

    String result = words.stream()
            .reduce("", (word1, word2) -> word1 + word2);

    System.out.println("The result is: " + result);
  }
}

Output: The result is: Thisiscodingblogfromalegru

Example 3

A program that sums up the grades of all students from the stream:

class Test {

  public static void main(String[] args) {
    int result = getStudents().stream()
            .map(Student::getGrade)
            .reduce(0, (grade1, grade2) -> grade1 + grade2);

    System.out.println("The result is: " + result);
    
  }

  private static List<Student> getStudents() {
    List<Student> students = new ArrayList<>();
    students.add(new Student("Steve", "Rogers", 8));
    students.add(new Student("John", "Doe", 5));
    students.add(new Student("Melissa", "Smith", 7));
    students.add(new Student("Megan", "Norton", 7));
    students.add(new Student("Tom", "Johnson", 9));

    return students;
  }
}

class Student {
  private String firstName;
  private String lastName;
  private int grade;

  public Student(String firstName, String lastName, int grade) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.grade = grade;
  }

  public int getGrade() {
    return this.grade;
  }
}

Output: The result is: 36

I hope this tutorial was helpful to you. To learn more, check out other Java Functional Programming tutorials.

Leave a Reply

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