Home > Java > javaTutorial > body text

How to Implement Nested Grouping in Java Using Collectors.groupingBy in Java 8?

Barbara Streisand
Release: 2024-10-24 08:54:30
Original
179 people have browsed it

How to Implement Nested Grouping in Java Using Collectors.groupingBy in Java 8?

Nested (Multi Level) Group By in Java 8

The need often arises to perform multi-level grouping of objects based on multiple keys. In this case, we have a set of classes representing data involving a list of items with a key and a list of subitems, also with a key. The goal is to group the items by their key and for each aggregation, further group the subitems by their key, resulting in a nested map.

Using Java 8's Collectors.groupingBy, we can achieve this by employing a combination of flatMap and a custom flat-mapping collector. We start by creating a temporary pair using Stream.flatMap to hold the combinations of items and subitems.

<code class="java">Map<T, Map<V, List<SubItem>>> result = pojo.getItems().stream()
        .flatMap(item -> item.subItems.stream()
                .map(sub -> new AbstractMap.SimpleImmutableEntry<>(item.getKey1(), sub)))
        .collect(Collectors.groupingBy(AbstractMap.SimpleImmutableEntry::getKey,
                Collectors.mapping(Map.Entry::getValue,
                        Collectors.groupingBy(SubItem::getKey2))));</code>
Copy after login

Alternatively, we can avoid creating temporary objects by using a flat-mapping collector, which unfortunately will not be available until Java 9. With this approach, the code simplifies to:

<code class="java">Map<T, Map<V, List<SubItem>>> result = pojo.getItems().stream()
        .collect(Collectors.groupingBy(Item::getKey1,
                Collectors.flatMapping(item -> item.getSubItems().stream(),
                        Collectors.groupingBy(SubItem::getKey2))));</code>
Copy after login

For users who may not want to wait for Java 9, a custom flat-mapping collector can be implemented:

<code class="java">static <T,U,A,R> Collector<T, ?, R> flatMapping(
        Function<? super T, ? extends Stream<? extends U>> mapper,
        Collector<? super U, A, R> downstream) {

        BiConsumer<A, ? super U> 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]));
}</code>
Copy after login

The above is the detailed content of How to Implement Nested Grouping in Java Using Collectors.groupingBy in Java 8?. For more information, please follow other related articles on the PHP Chinese website!

source:php
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!