Maison  >  Article  >  Java  >  Comment implémenter un regroupement imbriqué en Java à l'aide de Collectors.groupingBy dans Java 8 ?

Comment implémenter un regroupement imbriqué en Java à l'aide de Collectors.groupingBy dans Java 8 ?

Barbara Streisand
Barbara Streisandoriginal
2024-10-24 08:54:30163parcourir

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

Regrouper par imbriqué (multi-niveaux) dans Java 8

Le besoin se fait souvent sentir d'effectuer un regroupement d'objets à plusieurs niveaux en fonction de plusieurs clés . Dans ce cas, nous avons un ensemble de classes représentant des données impliquant une liste d'éléments avec une clé et une liste de sous-éléments, également avec une clé. L'objectif est de regrouper les éléments par leur clé et, pour chaque agrégation, de regrouper davantage les sous-éléments par leur clé, ce qui donne lieu à une carte imbriquée.

En utilisant Collectors.groupingBy de Java 8, nous pouvons y parvenir en employant une combinaison de flatMap et un collecteur de mappage plat personnalisé. Nous commençons par créer une paire temporaire à l'aide de Stream.flatMap pour contenir les combinaisons d'éléments et de sous-éléments.

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

Alternativement, nous pouvons éviter de créer des objets temporaires en utilisant un collecteur de mappage plat, qui ne sera malheureusement pas disponible jusqu'à Java 9. Avec cette approche, le code se simplifie comme suit :

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

Pour les utilisateurs qui ne souhaitent pas attendre Java 9, un collecteur de mappage plat personnalisé peut être implémenté :

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

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn