Java 8의 중첩(다중 수준) GroupBy
Java 8의 다중 수준 그룹화를 사용하면 다음을 기반으로 데이터 객체의 복잡한 집계가 가능합니다. 여러 필드. 귀하의 경우에는 Pojo, Item 및 SubItem 클래스 세트가 있고 key1을 기준으로 항목을 그룹화한 다음 key2를 기준으로 해당 그룹 내의 하위 항목을 그룹화하려고 합니다.
이를 달성하기 위해 간단하게 할 수는 없습니다. 중첩된 Collectors.groupingBy 호출을 사용하십시오. 이렇게 하면 서로 다른 객체의 여러 키로 그룹화할 수 없습니다. 대신 flatMap과 그룹화 수집기의 조합을 사용합니다.
<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.groupingBy(Map.Entry::getValue, Collectors.toList())));</code>
이 접근 방식에서는 먼저 flatMap을 사용하여 각 항목의 key1과 해당 하위 항목을 포함하는 쌍 스트림을 만듭니다. 그런 다음 Collectors.groupingBy를 두 번 적용합니다. 한 번은 키1을 기준으로 쌍을 그룹화하고 다시 한 번은 키2를 기준으로 하위 항목을 그룹화합니다.
대체 솔루션은 Java 9와 유사한 flatMapping 작업을 제공하는 사용자 정의 수집기를 정의하는 것입니다. Collectors.FlatMapping:
<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>
이 사용자 정의 컬렉터를 사용하면 그룹화 작업을 단순화할 수 있습니다.
<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>
위 내용은 복잡한 데이터 집계를 위해 Java 8에서 중첩된 GroupBy 작업을 수행하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!