"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Como implementar agrupamento multinível com objetos aninhados em Java 8?

Como implementar agrupamento multinível com objetos aninhados em Java 8?

Publicado em 2024-11-07
Navegar:411

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

Agrupamento multinível em Java 8 usando Nested GroupBy

Este artigo explora como implementar o agrupamento multinível ao lidar com classes aninhadas em Java 8. Especificamente, o objetivo é agrupar itens por um campo key1 e então, para cada grupo de itens, agrupá-los ainda mais por um campo key2. Em última análise, a saída deve ser um mapa com key1 como a chave externa e um mapa de key2 para uma lista de subitens.

A abordagem inicial tenta usar o método Collectors.groupingBy para conseguir isso, no entanto, é não é possível agrupar um único item diretamente por várias chaves. Para superar isso, uma operação flatMap é utilizada.

Um método envolve a criação de um par temporário usando Map.entrySet para armazenar combinações de itens e subitens antes da coleta. A outra abordagem, disponível em Java 9, aproveita o coletor flatMapping, que permite realizar a operação flatMap diretamente no coletor.

Aqui está a solução 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))));

Uma alternativa usando um coletor customizado em 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 coletor personalizado pode ser usado da seguinte forma:

Map>> result = pojo.getItems().stream()
    .collect(Collectors.groupingBy(Item::getKey1,
                Collectors.flatMapping(item -> item.getSubItems().stream(),
                    Collectors.groupingBy(SubItem::getKey2))));
Declaração de lançamento Este artigo foi reimpresso em: 1729730703 Se houver alguma violação, entre em contato com [email protected] para excluí-lo
Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3