Java groupingBy Collector

Collectors groupingBy method can be used to group objects by a specific property. This method will group the objects and store the results in a Java Map instance. If you are familiar with SQL this method can be considered similar to the GROUP BY clause.

Let’s look at some examples of how to use this method.

Grouping By A Single Property

Consider that we have a list of strings and we would like to group them by the number of characters in each string. We can achieve this as follows:

1
2
3
4
5
6
7
8
    List<String> words = List.of("one", "two","three",
        "four", "five", "six",
        "seven", "eight", "nine", "ten");

    Map<Integer, List<String>> wordsByWordCount =
        words.stream().collect(Collectors.groupingBy(String::length));

    System.out.println(wordsByWordCount);

The above code uses the groupingBy method to group the words by the number of characters in each word. If we run the above code we would receive the following output.

1
{3=[one, two, six, ten], 4=[four, five, nine], 5=[three, seven, eight]}

We can also change the type of the returned Map value type. For example we can return the list of words as a Set.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
public static void groupByCharacterLengthReturnSet() {
    List<String> words = List.of("one", "two","three",
        "four", "five", "six",
        "seven", "eight", "nine", "ten");

    Map<Integer, Set<String>> wordsByWordCount =
                words.stream().collect(Collectors.groupingBy(String::length, Collectors.toSet()));

    System.out.println(wordsByWordCount);
}

To achieve this we pass the Collector Collectors.toSet() to the Collectors.groupingBy method. If we execute the above code we receive the output:

1
{3=[six, one, ten, two], 4=[nine, four, five], 5=[seven, three, eight]}

Getting The Average Of The Grouped Result

Let’s continue by modifying the above example to group by the number of characters that have a length > than 4 and the corresponding average. We can achieve this by doing the following:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
public static void groupByCharacterLengthAndAverage() {
    List<String> words = List.of("one", "two","three",
        "four", "five", "six",
        "seven", "eight", "nine", "ten");

    Map<Boolean, Double> wordsByWordCount =
        words.stream().collect(Collectors.groupingBy((it) -> it.length() >  4,
            Collectors.averagingInt(String::length)));

    System.out.println(wordsByWordCount);
}

Above we use the Collectors.averagingInt method to find the average of a group. Executing the above code outputs:

1
{false=3.4285714285714284, true=5.0}

Getting The Sum Of The Grouped Result

We can also perform a summation on the grouped data.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
public static void groupByCharacterLengthAndSummation() {
    List<String> words = List.of("one", "two","three",
        "four", "five", "six",
        "seven", "eight", "nine", "ten");

    Map<Boolean, Integer> wordsByWordCount =
        words.stream().collect(Collectors.groupingBy((it) -> it.length() >  4,
        Collectors.summingInt(String::length)));

    System.out.println(wordsByWordCount);
}

Executing the above code outputs:

1
{false=24, true=15}

Conclusion

In this tutorial we looked at several examples of the groupingBy collector, that is available from Java8.