All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.hutool.core.collection.CollStreamUtil Maven / Gradle / Ivy

There is a newer version: 5.8.33
Show newest version
package cn.hutool.core.collection;


import cn.hutool.core.lang.Opt;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.stream.CollectorUtil;
import cn.hutool.core.stream.StreamUtil;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Collectors;

/**
 * 集合的stream操作封装
 *
 * @author [email protected], VampireAchao<[email protected]>Lion Li>
 * @since 5.5.2
 */
public class CollStreamUtil {

	/**
	 * 将collection转化为类型不变的map
* {@code Collection ----> Map} * * @param collection 需要转化的集合 * @param key V类型转化为K类型的lambda方法 * @param collection中的泛型 * @param map中的key类型 * @return 转化后的map */ public static Map toIdentityMap(Collection collection, Function key) { return toIdentityMap(collection, key, false); } /** * 将collection转化为类型不变的map
* {@code Collection ----> Map} * * @param collection 需要转化的集合 * @param key V类型转化为K类型的lambda方法 * @param isParallel 是否并行流 * @param collection中的泛型 * @param map中的key类型 * @return 转化后的map */ public static Map toIdentityMap(Collection collection, Function key, boolean isParallel) { if (CollUtil.isEmpty(collection)) { return MapUtil.newHashMap(0); } return toMap(collection, (v) -> Opt.ofNullable(v).map(key).get(), Function.identity(), isParallel); } /** * 将Collection转化为map(value类型与collection的泛型不同)
* {@code Collection -----> Map } * * @param collection 需要转化的集合 * @param key E类型转化为K类型的lambda方法 * @param value E类型转化为V类型的lambda方法 * @param collection中的泛型 * @param map中的key类型 * @param map中的value类型 * @return 转化后的map */ public static Map toMap(Collection collection, Function key, Function value) { return toMap(collection, key, value, false); } /** * @param collection 需要转化的集合 * @param key E类型转化为K类型的lambda方法 * @param value E类型转化为V类型的lambda方法 * @param isParallel 是否并行流 * @param collection中的泛型 * @param map中的key类型 * @param map中的value类型 * @return 转化后的map */ public static Map toMap(Collection collection, Function key, Function value, boolean isParallel) { if (CollUtil.isEmpty(collection)) { return MapUtil.newHashMap(0); } return StreamUtil.of(collection, isParallel) .collect(HashMap::new, (m, v) -> m.put(key.apply(v), value.apply(v)), HashMap::putAll); } /** * 将collection按照规则(比如有相同的班级id)分组成map
* {@code Collection -------> Map> } * * @param collection 需要分组的集合 * @param key 分组的规则 * @param collection中的泛型 * @param map中的key类型 * @return 分组后的map */ public static Map> groupByKey(Collection collection, Function key) { return groupByKey(collection, key, false); } /** * 将collection按照规则(比如有相同的班级id)分组成map
* {@code Collection -------> Map> } * * @param collection 需要分组的集合 * @param key 键分组的规则 * @param isParallel 是否并行流 * @param collection中的泛型 * @param map中的key类型 * @return 分组后的map */ public static Map> groupByKey(Collection collection, Function key, boolean isParallel) { if (CollUtil.isEmpty(collection)) { return MapUtil.newHashMap(0); } return groupBy(collection, key, Collectors.toList(), isParallel); } /** * 将collection按照两个规则(比如有相同的年级id,班级id)分组成双层map
* {@code Collection ---> Map>> } * * @param collection 需要分组的集合 * @param key1 第一个分组的规则 * @param key2 第二个分组的规则 * @param 集合元素类型 * @param 第一个map中的key类型 * @param 第二个map中的key类型 * @return 分组后的map */ public static Map>> groupBy2Key(Collection collection, Function key1, Function key2) { return groupBy2Key(collection, key1, key2, false); } /** * 将collection按照两个规则(比如有相同的年级id,班级id)分组成双层map
* {@code Collection ---> Map>> } * * @param collection 需要分组的集合 * @param key1 第一个分组的规则 * @param key2 第二个分组的规则 * @param isParallel 是否并行流 * @param 集合元素类型 * @param 第一个map中的key类型 * @param 第二个map中的key类型 * @return 分组后的map */ public static Map>> groupBy2Key(Collection collection, Function key1, Function key2, boolean isParallel) { if (CollUtil.isEmpty(collection)) { return MapUtil.newHashMap(0); } return groupBy(collection, key1, CollectorUtil.groupingBy(key2, Collectors.toList()), isParallel); } /** * 将collection按照两个规则(比如有相同的年级id,班级id)分组成双层map
* {@code Collection ---> Map> } * * @param collection 需要分组的集合 * @param key1 第一个分组的规则 * @param key2 第二个分组的规则 * @param 第一个map中的key类型 * @param 第二个map中的key类型 * @param collection中的泛型 * @return 分组后的map */ public static Map> group2Map(Collection collection, Function key1, Function key2) { return group2Map(collection, key1, key2, false); } /** * 将collection按照两个规则(比如有相同的年级id,班级id)分组成双层map
* {@code Collection ---> Map> } * * @param collection 需要分组的集合 * @param key1 第一个分组的规则 * @param key2 第二个分组的规则 * @param isParallel 是否并行流 * @param 第一个map中的key类型 * @param 第二个map中的key类型 * @param collection中的泛型 * @return 分组后的map */ public static Map> group2Map(Collection collection, Function key1, Function key2, boolean isParallel) { if (CollUtil.isEmpty(collection) || key1 == null || key2 == null) { return MapUtil.newHashMap(0); } return groupBy(collection, key1, CollectorUtil.toMap(key2, Function.identity(), (l, r) -> l), isParallel); } /** * 将collection按照规则(比如有相同的班级id)分组成map,map中的key为班级id,value为班级名
* {@code Collection -------> Map> } * * @param collection 需要分组的集合 * @param key 键分组的规则 * @param value 值分组的规则 * @param collection中的泛型 * @param map中的key类型 * @param List中的value类型 * @return 分组后的map */ public static Map> groupKeyValue(Collection collection, Function key, Function value) { return groupKeyValue(collection, key, value, false); } /** * 将collection按照规则(比如有相同的班级id)分组成map,map中的key为班级id,value为班级名
* {@code Collection -------> Map> } * * @param collection 需要分组的集合 * @param key 键分组的规则 * @param value 值分组的规则 * @param isParallel 是否并行流 * @param collection中的泛型 * @param map中的key类型 * @param List中的value类型 * @return 分组后的map */ public static Map> groupKeyValue(Collection collection, Function key, Function value, boolean isParallel) { if (CollUtil.isEmpty(collection)) { return MapUtil.newHashMap(0); } return groupBy(collection, key, Collectors.mapping(v -> Opt.ofNullable(v).map(value).orElse(null), Collectors.toList()), isParallel); } /** * 作为所有groupingBy的公共方法,更接近于原生,灵活性更强 * * @param collection 需要分组的集合 * @param key 第一次分组时需要的key * @param downstream 分组后需要进行的操作 * @param collection中的泛型 * @param map中的key类型 * @param 后续操作的返回值 * @return 分组后的map * @since 5.7.18 */ public static Map groupBy(Collection collection, Function key, Collector downstream) { if (CollUtil.isEmpty(collection)) { return MapUtil.newHashMap(0); } return groupBy(collection, key, downstream, false); } /** * 作为所有groupingBy的公共方法,更接近于原生,灵活性更强 * * @param collection 需要分组的集合 * @param key 第一次分组时需要的key * @param downstream 分组后需要进行的操作 * @param isParallel 是否并行流 * @param collection中的泛型 * @param map中的key类型 * @param 后续操作的返回值 * @return 分组后的map * @see Collectors#groupingBy(Function, Collector) * @since 5.7.18 */ public static Map groupBy(Collection collection, Function key, Collector downstream, boolean isParallel) { if (CollUtil.isEmpty(collection)) { return MapUtil.newHashMap(0); } return StreamUtil.of(collection, isParallel).collect(CollectorUtil.groupingBy(key, downstream)); } /** * 将collection转化为List集合,但是两者的泛型不同
* {@code Collection ------> List } * * @param collection 需要转化的集合 * @param function collection中的泛型转化为list泛型的lambda表达式 * @param collection中的泛型 * @param List中的泛型 * @return 转化后的list */ public static List toList(Collection collection, Function function) { return toList(collection, function, false); } /** * 将collection转化为List集合,但是两者的泛型不同
* {@code Collection ------> List } * * @param collection 需要转化的集合 * @param function collection中的泛型转化为list泛型的lambda表达式 * @param isParallel 是否并行流 * @param collection中的泛型 * @param List中的泛型 * @return 转化后的list */ public static List toList(Collection collection, Function function, boolean isParallel) { if (CollUtil.isEmpty(collection)) { return CollUtil.newArrayList(); } return StreamUtil.of(collection, isParallel) .map(function) .filter(Objects::nonNull) .collect(Collectors.toList()); } /** * 将collection转化为Set集合,但是两者的泛型不同
* {@code Collection ------> Set } * * @param collection 需要转化的集合 * @param function collection中的泛型转化为set泛型的lambda表达式 * @param collection中的泛型 * @param Set中的泛型 * @return 转化后的Set */ public static Set toSet(Collection collection, Function function) { return toSet(collection, function, false); } /** * 将collection转化为Set集合,但是两者的泛型不同
* {@code Collection ------> Set } * * @param collection 需要转化的集合 * @param function collection中的泛型转化为set泛型的lambda表达式 * @param isParallel 是否并行流 * @param collection中的泛型 * @param Set中的泛型 * @return 转化后的Set */ public static Set toSet(Collection collection, Function function, boolean isParallel) { if (CollUtil.isEmpty(collection)) { return CollUtil.newHashSet(); } return StreamUtil.of(collection, isParallel) .map(function) .filter(Objects::nonNull) .collect(Collectors.toSet()); } /** * 合并两个相同key类型的map * * @param map1 第一个需要合并的 map * @param map2 第二个需要合并的 map * @param merge 合并的lambda,将key value1 value2合并成最终的类型,注意value可能为空的情况 * @param map中的key类型 * @param 第一个 map的value类型 * @param 第二个 map的value类型 * @param 最终map的value类型 * @return 合并后的map */ public static Map merge(Map map1, Map map2, BiFunction merge) { if (MapUtil.isEmpty(map1) && MapUtil.isEmpty(map2)) { return MapUtil.newHashMap(0); } else if (MapUtil.isEmpty(map1)) { map1 = MapUtil.newHashMap(0); } else if (MapUtil.isEmpty(map2)) { map2 = MapUtil.newHashMap(0); } Set key = new HashSet<>(); key.addAll(map1.keySet()); key.addAll(map2.keySet()); Map map = MapUtil.newHashMap(key.size()); for (K t : key) { X x = map1.get(t); Y y = map2.get(t); V z = merge.apply(x, y); if (z != null) { map.put(t, z); } } return map; } }