"Si un trabajador quiere hacer bien su trabajo, primero debe afilar sus herramientas." - Confucio, "Las Analectas de Confucio. Lu Linggong"
Página delantera > Programación > ¿Cómo implementar agrupaciones multinivel con objetos anidados en Java 8?

¿Cómo implementar agrupaciones multinivel con objetos anidados en Java 8?

Publicado el 2024-11-07
Navegar:552

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

Agrupación multinivel en Java 8 usando Nested GroupBy

Este artículo explora cómo implementar agrupación multinivel cuando se trata de clases anidadas en Java 8. Específicamente, el objetivo es agrupar elementos por un campo clave1 y luego, para cada grupo de elementos, agruparlos por un campo clave2. En última instancia, el resultado debe ser un mapa con la clave1 como clave externa y un mapa de la clave2 para una lista de subelementos.

El enfoque inicial intenta utilizar el método Collectors.groupingBy para lograr esto, sin embargo, no es posible. No es posible agrupar un solo elemento mediante varias claves directamente. Para superar esto, se utiliza una operación flatMap.

Un método implica crear un par temporal usando Map.entrySet para contener combinaciones de elementos y subelementos antes de recopilarlos. El otro enfoque, disponible en Java 9, aprovecha el recopilador flatMapping, que permite realizar la operación flatMap directamente en el recopilador.

Aquí está la solución flatMap:

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

Una alternativa que utiliza un recopilador personalizado en 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]));
}

Este recopilador personalizado se puede utilizar de la siguiente manera:

Map>> result = pojo.getItems().stream()
    .collect(Collectors.groupingBy(Item::getKey1,
                Collectors.flatMapping(item -> item.getSubItems().stream(),
                    Collectors.groupingBy(SubItem::getKey2))));
Declaración de liberación Este artículo se reimprime en: 1729730703 Si hay alguna infracción, comuníquese con [email protected] para eliminarla.
Último tutorial Más>

Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.

Copyright© 2022 湘ICP备2022001581号-3