Многоуровневая группировка в Java 8 с использованием Nested GroupBy
В этой статье рассматривается, как реализовать многоуровневую группировку при работе с вложенными классами в Java 8. Java 8. В частности, цель состоит в том, чтобы сгруппировать элементы по полю key1, а затем для каждой группы элементов дополнительно сгруппировать их по полю key2. В конечном итоге выходные данные должны представлять собой карту с ключом 1 в качестве внешнего ключа и карту ключа 2 со списком подэлементов.
Первоначальный подход пытается использовать метод Collectors.groupingBy для достижения этой цели, однако это невозможно сгруппировать один элемент по нескольким ключам напрямую. Чтобы преодолеть эту проблему, используется операция FlatMap.
Один из методов предполагает создание временной пары с использованием Map.entrySet для хранения комбинаций элементов и подэлементов перед сбором. Другой подход, доступный в Java 9, использует сборщик FlatMapping, который позволяет выполнять операцию FlatMap непосредственно в сборщике.
Вот решение 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))));
Альтернатива с использованием пользовательского сборщика в 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]));
}
Этот пользовательский сборщик можно использовать следующим образом:
Map>> result = pojo.getItems().stream()
.collect(Collectors.groupingBy(Item::getKey1,
Collectors.flatMapping(item -> item.getSubItems().stream(),
Collectors.groupingBy(SubItem::getKey2))));
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3