Java Stream Group By Sum

Introduction

The Java Stream API provides powerful tools for data processing and manipulation. One common task is to group elements of a stream based on a certain property and then calculate the sum of a specific attribute within each group. This can be achieved using the groupingBy and summingInt collectors provided by the Stream API.

In this article, we will explore how to use the groupingBy and summingInt collectors to group elements and calculate the sum in Java streams.

Prerequisites

To follow along with the examples in this article, you will need a basic understanding of Java programming and the Stream API. You will also need a development environment with Java 8 or higher installed.

Grouping Elements and Calculating Sum

Let's say we have a list of Person objects, where each person has a name and an age. We want to group these persons by their age and calculate the sum of ages within each group.

public class Person {
    private String name;
    private int age;

    // Getter and setter methods here
}

To accomplish this, we can use the groupingBy collector from the Stream API. This collector groups elements based on a provided classifier function. In our case, the classifier function will return the age of each person.

Next, we can use the summingInt collector to calculate the sum of ages within each group. This collector takes as input a function that extracts the attribute to be summed, in our case, the age of each person.

Here's the code to achieve this:

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        List<Person> persons = Arrays.asList(
                new Person("John", 25),
                new Person("Jane", 30),
                new Person("Joe", 25),
                new Person("Jill", 30)
        );

        Map<Integer, Integer> ageSumByGroup = persons.stream()
                .collect(Collectors.groupingBy(Person::getAge, Collectors.summingInt(Person::getAge)));

        System.out.println(ageSumByGroup);
    }
}

Output:

{25=50, 30=60}

Flowchart

The following flowchart illustrates the process of grouping elements and calculating the sum using the Java Stream API:

flowchart TD
    A[Initialize List of Persons] --> B[Group by Age]
    B --> C[Calculate Sum of Ages]
    C --> D[Store Age-Sum Pairs]
    D --> E[Print Age-Sum Map]

Explanation

  1. We start by initializing a list of Person objects, where each person has a name and an age.
  2. We create a stream from the list of persons using the stream() method.
  3. We use the collect method to perform a reduction operation on the elements of the stream. Inside the collect method, we pass the groupingBy collector. This collector groups the persons based on their age using the Person::getAge method reference as a classifier function.
  4. We provide a second argument to the groupingBy collector. This argument is another collector, summingInt, which calculates the sum of ages within each group. We pass the Person::getAge method reference to the summingInt collector to extract the age attribute.
  5. The result of the collect method is a Map<Integer, Integer>, where the keys are the ages, and the values are the sums of ages within each group.
  6. Finally, we print the age-sum map to the console.

Conclusion

The Java Stream API provides powerful tools for data processing and manipulation. The groupingBy and summingInt collectors allow us to group elements based on a certain property and calculate the sum of a specific attribute within each group. This can be particularly useful when working with large datasets or performing complex data analysis tasks.

In this article, we have seen how to use the groupingBy and summingInt collectors to group elements and calculate the sum in Java streams. We have also provided a flowchart to visualize the process.

By leveraging the Stream API and its collectors, you can write concise and expressive code for data processing tasks in Java.

Happy coding!