From 01fc836e56edcc838f19831cdd961004a3813788 Mon Sep 17 00:00:00 2001 From: Looly Date: Sat, 22 Oct 2022 22:15:09 +0800 Subject: [PATCH] =?UTF-8?q?CollectorUtil=E6=B7=BB=E5=8A=A0=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=AF=B9=E5=80=BC=E9=9B=86=E5=90=88=E8=BF=9B=E8=A1=8C?= =?UTF-8?q?=E6=98=A0=E5=B0=84=E7=9A=84=E5=88=86=E7=BB=84=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + .../cn/hutool/core/stream/CollectorUtil.java | 63 +++++++++++++++++++ .../java/cn/hutool/core/map/MapUtilTest.java | 8 +++ .../hutool/core/stream/CollectorUtilTest.java | 26 ++++++++ 4 files changed, 98 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d24cac2e..5f8233562 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ * 【core 】 UrlBuilder增加getPortWithDefault方法(pr#835@Gitee) * 【core 】 FuncKeyMap的子类,传入可被序列化的keyFunc(pr#838@Gitee) * 【extra 】 SpringUtil支持SpringBoot3自动配置(pr#839@Gitee) +* 【core 】 CollectorUtil添加支持对值集合进行映射的分组方法(pr#844@Gitee) ### 🐞Bug修复 * 【poi 】 修复ExcelReader读取只有标题行报错问题(issue#I5U1JA@Gitee) diff --git a/hutool-core/src/main/java/cn/hutool/core/stream/CollectorUtil.java b/hutool-core/src/main/java/cn/hutool/core/stream/CollectorUtil.java index 9bd5a7727..f474c53ea 100644 --- a/hutool-core/src/main/java/cn/hutool/core/stream/CollectorUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/stream/CollectorUtil.java @@ -4,6 +4,7 @@ import cn.hutool.core.lang.Opt; import cn.hutool.core.util.StrUtil; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.EnumSet; import java.util.HashMap; @@ -248,4 +249,66 @@ public class CollectorUtil { ); } + /** + * 提供对null值友好的groupingBy操作的{@link Collector}实现, + * 对集合分组,然后对分组后的值集合进行映射 + * + * @param classifier 分组依据 + * @param valueMapper 值映射方法 + * @param valueCollFactory 值集合的工厂方法 + * @param mapFactory Map集合的工厂方法 + * @param 元素类型 + * @param 键类型 + * @param 值类型 + * @param 值集合类型 + * @param 返回的Map集合类型 + * @return {@link Collector} + */ + public static , M extends Map> Collector groupingBy( + final Function classifier, + final Function valueMapper, + final Supplier valueCollFactory, + final Supplier mapFactory) { + return groupingBy(classifier, mapFactory, Collectors.mapping( + valueMapper, Collectors.toCollection(valueCollFactory) + )); + } + + /** + * 提供对null值友好的groupingBy操作的{@link Collector}实现, + * 对集合分组,然后对分组后的值集合进行映射 + * + * @param classifier 分组依据 + * @param valueMapper 值映射方法 + * @param valueCollFactory 值集合的工厂方法 + * @param 元素类型 + * @param 键类型 + * @param 值类型 + * @param 值集合类型 + * @return {@link Collector} + */ + public static > Collector> groupingBy( + final Function classifier, + final Function valueMapper, + final Supplier valueCollFactory) { + return groupingBy(classifier, valueMapper, valueCollFactory, HashMap::new); + } + + /** + * 提供对null值友好的groupingBy操作的{@link Collector}实现, + * 对集合分组,然后对分组后的值集合进行映射 + * + * @param classifier 分组依据 + * @param valueMapper 值映射方法 + * @param 元素类型 + * @param 键类型 + * @param 值类型 + * @return {@link Collector} + */ + public static Collector>> groupingBy( + final Function classifier, + final Function valueMapper) { + return groupingBy(classifier, valueMapper, ArrayList::new, HashMap::new); + } + } diff --git a/hutool-core/src/test/java/cn/hutool/core/map/MapUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/map/MapUtilTest.java index 0f371b072..56c6fa983 100644 --- a/hutool-core/src/test/java/cn/hutool/core/map/MapUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/map/MapUtilTest.java @@ -1,6 +1,7 @@ package cn.hutool.core.map; import cn.hutool.core.convert.Convert; +import cn.hutool.core.lang.Dict; import cn.hutool.core.lang.Opt; import cn.hutool.core.util.StrUtil; import lombok.Builder; @@ -224,4 +225,11 @@ public class MapUtilTest { final Integer age = MapUtil.getInt(map, "age"); Assert.assertNotNull(age); } + + @Test + public void joinIgnoreNullTest() { + final Dict v1 = Dict.of().set("id", 12).set("name", "张三").set("age", null); + final String s = MapUtil.joinIgnoreNull(v1, ",", "="); + Assert.assertEquals("id=12,name=张三", s); + } } diff --git a/hutool-core/src/test/java/cn/hutool/core/stream/CollectorUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/stream/CollectorUtilTest.java index 0c8e3c560..bd8a415ba 100644 --- a/hutool-core/src/test/java/cn/hutool/core/stream/CollectorUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/stream/CollectorUtilTest.java @@ -5,6 +5,9 @@ import org.junit.Assert; import org.junit.Test; import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -27,4 +30,27 @@ public class CollectorUtilTest { .put("特拉叙马霍斯", Arrays.asList(3, 1, 2)).build(), nameScoresMap); } + + @Test + public void testGroupingByAfterValueMapped() { + 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)); + + Assert.assertEquals(LinkedHashMap.class, map.getClass()); + Assert.assertEquals(new LinkedHashSet<>(Arrays.asList("2", "4")), map.get(Boolean.TRUE)); + Assert.assertEquals(new LinkedHashSet<>(Arrays.asList("1", "3")), map.get(Boolean.FALSE)); + + map = list.stream() + .collect(CollectorUtil.groupingBy(t -> (t & 1) == 0, String::valueOf, LinkedHashSet::new)); + Assert.assertEquals(HashMap.class, map.getClass()); + Assert.assertEquals(new LinkedHashSet<>(Arrays.asList("2", "4")), map.get(Boolean.TRUE)); + Assert.assertEquals(new LinkedHashSet<>(Arrays.asList("1", "3")), map.get(Boolean.FALSE)); + + final Map> map2 = list.stream() + .collect(CollectorUtil.groupingBy(t -> (t & 1) == 0, String::valueOf)); + Assert.assertEquals(Arrays.asList("2", "2", "4"), map2.get(Boolean.TRUE)); + Assert.assertEquals(Arrays.asList("1", "1", "3"), map2.get(Boolean.FALSE)); + + } }