Grouping by Multiple Fields in Java 8
When grouping objects by a field name, Java 8 provides the Collectors.groupingBy() method. However, what if we need to group by multiple fields?
Option 1: Chaining Collectors
One approach is to chain multiple Collectors.groupingBy() calls:
Map<String, Map<Integer, List<Person>>> map = people .collect(Collectors.groupingBy(Person::getName, Collectors.groupingBy(Person::getAge)));
This creates a nested map where the first level is grouped by name and the second level is grouped by age. To retrieve a list of 18-year-old people named Fred:
map.get("Fred").get(18);
Option 2: Defining a Grouping Record
Alternatively, we can create a class (e.g., NameAge) that represents the grouping fields:
class NameAge implements Comparable<NameAge> { String name; int age; // Constructor, getters, compareTo, etc. }
Then, group by the NameAge record:
Map<NameAge, List<Person>> map = people .collect(Collectors.groupingBy(Person::getNameAge));
To retrieve:
map.get(new NameAge("Fred", 18));
Option 3: Using Pair Class
If implementing a custom grouping record is undesirable, we can utilize a pair class from libraries like Apache Commons or Java's new java.util.function.Pair. For example, with Apache Commons:
Map<Pair<String, Integer>, List<Person>> map = people.collect(Collectors.groupingBy(p -> Pair.of(p.getName(), p.getAge())));
To retrieve:
map.get(Pair.of("Fred", 18));
Recommendation
The choice of approach depends on the specific requirements. Records offer a concise and clear solution, but libraries like Apache Commons may be preferred for more complex scenarios.
The above is the detailed content of How Can I Group Data by Multiple Fields Using Java 8 Streams?. For more information, please follow other related articles on the PHP Chinese website!