mirror of
https://gitee.com/dromara/hutool.git
synced 2025-04-05 17:37:59 +08:00
CollectorUtil添加支持对值集合进行映射的分组方法
This commit is contained in:
parent
92003ecbfb
commit
01fc836e56
@ -14,6 +14,7 @@
|
|||||||
* 【core 】 UrlBuilder增加getPortWithDefault方法(pr#835@Gitee)
|
* 【core 】 UrlBuilder增加getPortWithDefault方法(pr#835@Gitee)
|
||||||
* 【core 】 FuncKeyMap的子类,传入可被序列化的keyFunc(pr#838@Gitee)
|
* 【core 】 FuncKeyMap的子类,传入可被序列化的keyFunc(pr#838@Gitee)
|
||||||
* 【extra 】 SpringUtil支持SpringBoot3自动配置(pr#839@Gitee)
|
* 【extra 】 SpringUtil支持SpringBoot3自动配置(pr#839@Gitee)
|
||||||
|
* 【core 】 CollectorUtil添加支持对值集合进行映射的分组方法(pr#844@Gitee)
|
||||||
|
|
||||||
### 🐞Bug修复
|
### 🐞Bug修复
|
||||||
* 【poi 】 修复ExcelReader读取只有标题行报错问题(issue#I5U1JA@Gitee)
|
* 【poi 】 修复ExcelReader读取只有标题行报错问题(issue#I5U1JA@Gitee)
|
||||||
|
@ -4,6 +4,7 @@ import cn.hutool.core.lang.Opt;
|
|||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.HashMap;
|
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 <T> 元素类型
|
||||||
|
* @param <K> 键类型
|
||||||
|
* @param <R> 值类型
|
||||||
|
* @param <C> 值集合类型
|
||||||
|
* @param <M> 返回的Map集合类型
|
||||||
|
* @return {@link Collector}
|
||||||
|
*/
|
||||||
|
public static <T, K, R, C extends Collection<R>, M extends Map<K, C>> Collector<T, ?, M> groupingBy(
|
||||||
|
final Function<? super T, ? extends K> classifier,
|
||||||
|
final Function<? super T, ? extends R> valueMapper,
|
||||||
|
final Supplier<C> valueCollFactory,
|
||||||
|
final Supplier<M> mapFactory) {
|
||||||
|
return groupingBy(classifier, mapFactory, Collectors.mapping(
|
||||||
|
valueMapper, Collectors.toCollection(valueCollFactory)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提供对null值友好的groupingBy操作的{@link Collector}实现,
|
||||||
|
* 对集合分组,然后对分组后的值集合进行映射
|
||||||
|
*
|
||||||
|
* @param classifier 分组依据
|
||||||
|
* @param valueMapper 值映射方法
|
||||||
|
* @param valueCollFactory 值集合的工厂方法
|
||||||
|
* @param <T> 元素类型
|
||||||
|
* @param <K> 键类型
|
||||||
|
* @param <R> 值类型
|
||||||
|
* @param <C> 值集合类型
|
||||||
|
* @return {@link Collector}
|
||||||
|
*/
|
||||||
|
public static <T, K, R, C extends Collection<R>> Collector<T, ?, Map<K, C>> groupingBy(
|
||||||
|
final Function<? super T, ? extends K> classifier,
|
||||||
|
final Function<? super T, ? extends R> valueMapper,
|
||||||
|
final Supplier<C> valueCollFactory) {
|
||||||
|
return groupingBy(classifier, valueMapper, valueCollFactory, HashMap::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提供对null值友好的groupingBy操作的{@link Collector}实现,
|
||||||
|
* 对集合分组,然后对分组后的值集合进行映射
|
||||||
|
*
|
||||||
|
* @param classifier 分组依据
|
||||||
|
* @param valueMapper 值映射方法
|
||||||
|
* @param <T> 元素类型
|
||||||
|
* @param <K> 键类型
|
||||||
|
* @param <R> 值类型
|
||||||
|
* @return {@link Collector}
|
||||||
|
*/
|
||||||
|
public static <T, K, R> Collector<T, ?, Map<K, List<R>>> groupingBy(
|
||||||
|
final Function<? super T, ? extends K> classifier,
|
||||||
|
final Function<? super T, ? extends R> valueMapper) {
|
||||||
|
return groupingBy(classifier, valueMapper, ArrayList::new, HashMap::new);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package cn.hutool.core.map;
|
package cn.hutool.core.map;
|
||||||
|
|
||||||
import cn.hutool.core.convert.Convert;
|
import cn.hutool.core.convert.Convert;
|
||||||
|
import cn.hutool.core.lang.Dict;
|
||||||
import cn.hutool.core.lang.Opt;
|
import cn.hutool.core.lang.Opt;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
@ -224,4 +225,11 @@ public class MapUtilTest {
|
|||||||
final Integer age = MapUtil.getInt(map, "age");
|
final Integer age = MapUtil.getInt(map, "age");
|
||||||
Assert.assertNotNull(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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,9 @@ import org.junit.Assert;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -27,4 +30,27 @@ public class CollectorUtilTest {
|
|||||||
.put("特拉叙马霍斯", Arrays.asList(3, 1, 2)).build(),
|
.put("特拉叙马霍斯", Arrays.asList(3, 1, 2)).build(),
|
||||||
nameScoresMap);
|
nameScoresMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGroupingByAfterValueMapped() {
|
||||||
|
List<Integer> list = Arrays.asList(1, 1, 2, 2, 3, 4);
|
||||||
|
Map<Boolean, Set<String>> 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<Boolean, List<String>> 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));
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user