Multi-Level Grouping in Java 8 Using Nested GroupBy
This article explores how to implement multi-level grouping when dealing with nested classes in Java 8. Specifically, the goal is to group items by a key1 field and then, for each group of items, further group them by a key2 field. Ultimately, the output should be a map with key1 as the outer key and a map of key2 to a list of subitems.
The initial approach attempts to use the Collectors.groupingBy method to achieve this, however, it is not possible to group a single item by multiple keys directly. To overcome this, a flatMap operation is utilized.
One method involves creating a temporary pair using Map.entrySet to hold combinations of items and subitems before collecting. The other approach, available in Java 9, leverages the flatMapping collector, which enables performing the flatMap operation directly in the collector.
Here's the flatMap solution:
Map>> result = pojo.getItems().stream()
.flatMap(item -> item.getSubItems().stream()
.map(sub -> new AbstractMap.SimpleImmutableEntry(item.getKey1(), sub)))
.collect(Collectors.groupingBy(AbstractMap.SimpleImmutableEntry::getKey,
Collectors.mapping(Map.Entry::getValue,
Collectors.groupingBy(SubItem::getKey2))));
An alternative using a custom collector in Java 8:
static Collector flatMapping(
Function super T,? extends Stream extends U>> mapper,
Collector super U,A,R> downstream) {
BiConsumer acc = downstream.accumulator();
return Collector.of(downstream.supplier(),
(a, t) -> { try(Stream extends U> s=mapper.apply(t)) {
if(s!=null) s.forEachOrdered(u -> acc.accept(a, u));
}},
downstream.combiner(), downstream.finisher(),
downstream.characteristics().toArray(new Collector.Characteristics[0]));
}
This custom collector can be used as follows:
Map>> result = pojo.getItems().stream()
.collect(Collectors.groupingBy(Item::getKey1,
Collectors.flatMapping(item -> item.getSubItems().stream(),
Collectors.groupingBy(SubItem::getKey2))));
Disclaimer: All resources provided are partly from the Internet. If there is any infringement of your copyright or other rights and interests, please explain the detailed reasons and provide proof of copyright or rights and interests and then send it to the email: [email protected] We will handle it for you as soon as possible.
Copyright© 2022 湘ICP备2022001581号-3