How to do GROUP BY in Java 8? Collectors.groupingBy() Example (original) (raw)

Java 8 now directly allows you to do GROUP BY in Java by using Collectors.groupingBy() method. GROUP BY is a very useful aggregate operation from SQL. It allows you to group records on certain criteria. How do you group by in Java? For example, suppose you have a list of Persons, How do you group persons by their city. London, Paris, or Tokyo? Well, we can do that by using a for loop, checking each person, and putting them on a list of HashMap with the same city, but in Java 8, you don't need to hack your way like that, you have a much cleaner solution. You can use Stream and Collector which provides groupingBy() method to do this.

Since its one of the most common ways to aggregate data, it has a real benefit, coupled that with the various overloaded version of groupingBy() method which also allows you to perform grouping objects concurrently by using concurrent Collectors.

In this Java 8 tutorial, you will learn how to group by a list of objects based on their properties. For those, who think Java 8 is just about lambda expression, it's not true, there are so many goodies released in JDK 1.8 and you will be amazed once you start using them.

And, If you are serious about improving Java functional programming skills then I highly recommend you check out these best Java Collections and Stream courses, which explains both Functional Programming and Java Stream fundamentals in good detail

How to group objects in Java 8? Example

Here is our sample program to group objects on their properties in Java 8 and earlier version. First, we'll take a look at how could we do this in pre-Java 8 world, and later we'll Java 8 example of the group by. By looking at both approaches you can realize that Java 8 has really made your task much easier.

In Java SE 6 or 7, in order to create a group of objects from a list, you need to iterate over the list, check each element and put them into their own respective list. You also need a Map to store these groups. When you got the first item for a new group, you create a list and put that item on the list, but when the group already exists in Map then you just retrieve it and store your element into it.

The code is not difficult to write but it takes 5 to 6 lines to do that and you have to do null check everywhere to avoid NullPointerException. Compare that to one line code of Java 8, where you get the stream from the list and used a Collector to group them. All you need to do is pass the grouping criterion to the collector and its done.

This way, you can create multiple groups by just changing the grouping criterion. In the earlier version, you have to write the same 5 to 6 lines of code to create a group of different criteria.

How to create groups of Objects in Java 8

You can even perform several aggregate functions like sum(), count(), max(), min() in individual groups by taking advantage of new Stream API, as shown in my earlier streams examples. After all individual groups are just a list of objects and you can get the stream by just calling stream() method on that. In short, you can now do the SQL style group by Java without using any loop.

Java Program to Group Objects

import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.stream.Collectors;

/**

}

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

public Person(String name, String city, int age) {
    this.name = name;
    this.city = city;
    this.age = age;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getCity() {
    return city;
}

public void setCity(String city) {
    this.city = city;
}

public int getAge() {
    return age;
}

public void setAge(int age) {
    this.age = age;
}

@Override
public String toString() {
    return String.format("%s(%s,%d)", name, city, age);
}

@Override
public int hashCode() {
    int hash = 7;
    hash = 79 * hash + Objects.hashCode(this.name);
    hash = 79 * hash + Objects.hashCode(this.city);
    hash = 79 * hash + this.age;
    return hash;
}

@Override
public boolean equals(Object obj) {
    if (obj == null) {
        return false;
    }
    if (getClass() != obj.getClass()) {
        return false;
    }
    final Person other = (Person) obj;
    if (!Objects.equals(this.name, other.name)) {
        return false;
    }
    if (!Objects.equals(this.city, other.city)) {
        return false;
    }
    if (this.age != other.age) {
        return false;
    }
    return true;
}

}

Output : Person grouped by cities : { Tokyo=[Monobo(Tokyo,23)], London=[John(London,21), Swann(London,21), Kevin(London,23)], Paris=[Sam(Paris,23), Nadal(Paris,31)] }

Person grouped by cities in Java 8: { Tokyo=[Monobo(Tokyo,23)], London=[John(London,21), Swann(London,21), Kevin(London,23)], Paris=[Sam(Paris,23), Nadal(Paris,31)] }

Person grouped by age in Java 8: { 21=[John(London,21), Swann(London,21)], 23=[Kevin(London,23), Monobo(Tokyo,23), Sam(Paris,23)], 31=[Nadal(Paris,31)] }

In this example, we are a grouping list of Person objects by their city. In our list, we have 3 persons from London, 2 from Paris and one from Tokyo. After grouping them by the city, you can see that they are in their own List, there is one person in the list of Tokyo, 3 persons in the list of London, and 2 persons in the list of Paris. Both Java 7 and Java 8 example has produced identical groups.

Later, we have also created another group by dividing them by their age and you can see that we have 3 groups for different age groups, 21, 23, and 31.

That's all about how to do group by in Java 8. You can now more easily create a group of objects on arbitrary criteria than ever before. Java 8 Collectors class also provide several overloaded version of the groupingBy() function for more sophisticated grouping. You can even do a group by concurrently by using groupingByConcurrent() method from java.util.streams.Collectors class.

Related Java 8 Tutorials
If you are interested in learning more about new features of Java 8, here are my earlier articles covering some of the important concepts of Java 8: