Collect results of groupingBy() into different map implementation

Overview

In Java, the groupingBy() method collects the results to HashMap implementation of the Map interface by default. In this shot, we’ll learn how to collect the results in a different implementation of Map such as TreeMap.

Note: Refer to this shot about grouping() to learn more about the method.

mapFactory parameter

The groupingBy() method optionally accepts the mapFactory parameter, which provides a new empty map into which the results of the group by operation will be stored. This parameter is an implementation of the Supplier interface that provides an empty map.

Syntax

public static <T, K, D, A, M extends Map<K, D>> Collector<T, ?, M> groupingBy(Function<? super T, ? extends K> classifier, Supplier<M> mapFactory, Collector<? super T, A, D> downstream)

Parameters

  • Function<? super T, ? extends K> classifier: This is the classification function.
  • Collector<? super T, A, D> downstream: This is the collector implementing downstream reduction operation.
  • Supplier<M> mapFactory: This is the supplier that provides a map into which results are inserted.

Example

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
public class Main {
static class Student{
String firstName;
String lastName;
public Student(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
@Override
public String toString() {
return "Student{" +
"firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
'}';
}
}
public static void main(String[] args){
List<Student> studentList = Arrays.asList(new Student("sam", "collins"),
new Student("lilly", "collins"),
new Student("john", "adkins"),
new Student("jasmine", "adkins"),
new Student("kite", "mason"));
Function<Student, String> classificationFunction = student -> student.lastName;
Supplier<Map<String, List<Student>>> mapSupplier = TreeMap::new;
Map<String, List<Student>> groupedStudents = studentList.stream().collect(Collectors.groupingBy(classificationFunction, mapSupplier, Collectors.toList()));
System.out.println("Number of students in each group grouped according to their last name - \n" + groupedStudents);
}
}

Explanation

  • Lines 1–7: We import the relevant classes.
  • Lines 11–27: We define a Student class that consists of the firstName and lastName as fields. The class has a constructor that initializes the value of the fields and a toString() method implementation.
  • Lines 30–34: We create a list of student objects.
  • Line 36: We define the classificationFunction because it returns the lastName value for every Student object passed.
  • Line 37: We create a supplier that provides a map into which results are inserted.
  • Line 38: We create groupedStudents and get respected results into this map.
  • Line 39: We print the results.