From 7a4cac2963418556a51ec8d2b2274c9c4cc2fe3a Mon Sep 17 00:00:00 2001 From: Looly Date: Sun, 12 Nov 2023 16:46:10 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8DCollectorUtil.reduceListMap?= =?UTF-8?q?=E4=B8=8Ecollectors.groupby=E4=B8=80=E8=B5=B7=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E6=97=B6=E5=87=BA=E7=8E=B0=E4=B8=8E=E9=A2=84=E6=9C=9F=E4=B8=8D?= =?UTF-8?q?=E7=AC=A6=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hutool/core/stream/CollectorUtil.java | 57 ++++++++++--------- .../hutool/core/stream/CollectorUtilTest.java | 21 ++++++- 2 files changed, 50 insertions(+), 28 deletions(-) diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/stream/CollectorUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/stream/CollectorUtil.java index 4437cadbb..26903c78f 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/stream/CollectorUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/stream/CollectorUtil.java @@ -35,7 +35,7 @@ public class CollectorUtil { * 说明已包含IDENTITY_FINISH特征 为 Characteristics.IDENTITY_FINISH 的缩写 */ public static final Set CH_ID - = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH)); + = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH)); /** * 说明不包含IDENTITY_FINISH特征 */ @@ -80,11 +80,11 @@ public class CollectorUtil { final CharSequence suffix, final Function toStringFunc) { return new SimpleCollector<>( - () -> new StringJoiner(delimiter, prefix, suffix), - (joiner, ele) -> joiner.add(toStringFunc.apply(ele)), - StringJoiner::merge, - StringJoiner::toString, - Collections.emptySet() + () -> new StringJoiner(delimiter, prefix, suffix), + (joiner, ele) -> joiner.add(toStringFunc.apply(ele)), + StringJoiner::merge, + StringJoiner::toString, + Collections.emptySet() ); } @@ -208,11 +208,11 @@ public class CollectorUtil { * 提供对null值友好的groupingBy操作的{@link Collector}实现, * 对集合分组,然后对分组后的值集合进行映射 * - * @param classifier 分组依据 - * @param valueMapper 值映射方法 - * @param 元素类型 - * @param 键类型 - * @param 值类型 + * @param classifier 分组依据 + * @param valueMapper 值映射方法 + * @param 元素类型 + * @param 键类型 + * @param 值类型 * @return {@link Collector} */ public static Collector>> groupingBy( @@ -284,7 +284,7 @@ public class CollectorUtil { final BinaryOperator mergeFunction, final Supplier mapSupplier) { final BiConsumer accumulator - = (map, element) -> map.put(Opt.ofNullable(element).map(keyMapper).get(), Opt.ofNullable(element).map(valueMapper).get()); + = (map, element) -> map.put(Opt.ofNullable(element).map(keyMapper).get(), Opt.ofNullable(element).map(valueMapper).get()); return new SimpleCollector<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_ID); } @@ -330,13 +330,18 @@ public class CollectorUtil { */ public static >> Collector, ?, R> reduceListMap(final Supplier mapSupplier) { return Collectors.reducing(mapSupplier.get(), value -> { - final R result = mapSupplier.get(); - value.forEach((k, v) -> result.computeIfAbsent(k, i -> new ArrayList<>()).add(v)); - return result; - }, (l, r) -> { - r.forEach((k, v) -> l.computeIfAbsent(k, i -> new ArrayList<>()).addAll(v)); - return l; - } + final R result = mapSupplier.get(); + value.forEach((k, v) -> result.computeIfAbsent(k, i -> new ArrayList<>()).add(v)); + return result; + }, (l, r) -> { + final R resultMap = mapSupplier.get(); + resultMap.putAll(l); + r.forEach((k, v) -> { + final List list = resultMap.computeIfAbsent(k, i -> new ArrayList<>()); + list.addAll(v); + }); + return resultMap; + } ); } @@ -350,7 +355,7 @@ public class CollectorUtil { * @since 6.0.0 */ public static Collector, EntryStream> toEntryStream( - final Function keyMapper) { + final Function keyMapper) { return toEntryStream(keyMapper, Function.identity()); } @@ -366,7 +371,7 @@ public class CollectorUtil { * @since 6.0.0 */ public static Collector, EntryStream> toEntryStream( - final Function keyMapper, final Function valueMapper) { + final Function keyMapper, final Function valueMapper) { Objects.requireNonNull(keyMapper); Objects.requireNonNull(valueMapper); return transform(ArrayList::new, list -> EntryStream.of(list, keyMapper, valueMapper)); @@ -401,11 +406,11 @@ public class CollectorUtil { * @since 6.0.0 */ public static > Collector transform( - final Supplier collFactory, final Function mapper) { + final Supplier collFactory, final Function mapper) { Objects.requireNonNull(collFactory); Objects.requireNonNull(mapper); return new SimpleCollector<>( - collFactory, C::add, (l1, l2) -> { + collFactory, C::add, (l1, l2) -> { l1.addAll(l2); return l1; }, mapper, CH_NOID @@ -458,8 +463,8 @@ public class CollectorUtil { final Collector downstream) { final BiConsumer downstreamAccumulator = downstream.accumulator(); return new SimpleCollector<>(downstream.supplier(), - (r, t) -> Opt.of(t).filter(predicate).ifPresent(e -> downstreamAccumulator.accept(r, e)), - downstream.combiner(), downstream.finisher(), - downstream.characteristics()); + (r, t) -> Opt.of(t).filter(predicate).ifPresent(e -> downstreamAccumulator.accept(r, e)), + downstream.combiner(), downstream.finisher(), + downstream.characteristics()); } } diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/stream/CollectorUtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/stream/CollectorUtilTest.java index e008ef254..3f7cf3363 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/stream/CollectorUtilTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/stream/CollectorUtilTest.java @@ -12,6 +12,7 @@ package org.dromara.hutool.core.stream; +import org.dromara.hutool.core.collection.ListUtil; import org.dromara.hutool.core.map.MapUtil; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -44,6 +45,22 @@ public class CollectorUtilTest { Assertions.assertEquals(MapUtil.builder("苏格拉底", Arrays.asList(1, 2)) .put("特拉叙马霍斯", Arrays.asList(3, 1, 2)).build(), nameScoresMap); + + final List> data = ListUtil.of( + MapUtil.builder("name", "sam").put("count", "80").map(), + MapUtil.builder("name", "sam").put("count", "81").map(), + MapUtil.builder("name", "sam").put("count", "82").map(), + MapUtil.builder("name", "jack").put("count", "80").map(), + MapUtil.builder("name", "jack").put("count", "90").map() + ); + + final Map>> nameMap = data.stream() + .collect(Collectors.groupingBy(e -> e.get("name"), CollectorUtil.reduceListMap())); + Assertions.assertEquals(MapUtil.builder("jack", MapUtil.builder("name", Arrays.asList("jack", "jack")) + .put("count", Arrays.asList("80", "90")).build()) + .put("sam", MapUtil.builder("name", Arrays.asList("sam", "sam", "sam")) + .put("count", Arrays.asList("80", "81", "82")).build()) + .build(), nameMap); } @Test @@ -93,7 +110,7 @@ public class CollectorUtilTest { @Test public void testGroupingByAfterValueMapped() { - List list = Arrays.asList(1, 1, 2, 2, 3, 4); + final List list = Arrays.asList(1, 1, 2, 2, 3, 4); Map> map = list.stream() .collect(CollectorUtil.groupingBy(t -> (t & 1) == 0, String::valueOf, LinkedHashSet::new, LinkedHashMap::new)); @@ -107,7 +124,7 @@ public class CollectorUtilTest { Assertions.assertEquals(new LinkedHashSet<>(Arrays.asList("2", "4")), map.get(Boolean.TRUE)); Assertions.assertEquals(new LinkedHashSet<>(Arrays.asList("1", "3")), map.get(Boolean.FALSE)); - Map> map2 = list.stream() + final Map> map2 = list.stream() .collect(CollectorUtil.groupingBy(t -> (t & 1) == 0, String::valueOf)); Assertions.assertEquals(Arrays.asList("2", "2", "4"), map2.get(Boolean.TRUE)); Assertions.assertEquals(Arrays.asList("1", "1", "3"), map2.get(Boolean.FALSE));