Home  >  Article  >  Java  >  How to Implement Multi-Level Grouping with Nested Objects in Java 8?

How to Implement Multi-Level Grouping with Nested Objects in Java 8?

Patricia Arquette
Patricia ArquetteOriginal
2024-10-24 08:47:30701browse

How to Implement Multi-Level Grouping with Nested Objects in Java 8?

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:

<code class="java">Map<T, Map<V, List<SubItem>>> 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))));</code>

An alternative using a custom collector in Java 8:

<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>

This custom collector can be used as follows:

<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>

The above is the detailed content of How to Implement Multi-Level Grouping with Nested Objects in Java 8?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
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