|
@@ -0,0 +1,259 @@
|
|
|
|
+package com.ruoyi.common.utils;
|
|
|
|
+
|
|
|
|
+import org.apache.commons.collections4.MapUtils;
|
|
|
|
+import org.springframework.util.CollectionUtils;
|
|
|
|
+
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
+import java.util.Collection;
|
|
|
|
+import java.util.Comparator;
|
|
|
|
+import java.util.HashMap;
|
|
|
|
+import java.util.HashSet;
|
|
|
|
+import java.util.LinkedHashMap;
|
|
|
|
+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.function.Predicate;
|
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
+import java.util.stream.IntStream;
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * stream 流工具类
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+public class StreamUtils {
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 将collection过滤
|
|
|
|
+ *
|
|
|
|
+ * @param collection 需要转化的集合
|
|
|
|
+ * @param function 过滤方法
|
|
|
|
+ * @return 过滤后的list
|
|
|
|
+ */
|
|
|
|
+ public static <E> List<E> filter(Collection<E> collection, Predicate<E> function) {
|
|
|
|
+ if (CollectionUtils.isEmpty(collection)) {
|
|
|
|
+ return new ArrayList<>();
|
|
|
|
+ }
|
|
|
|
+ return collection.stream().filter(function).collect(Collectors.toList());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 将collection拼接
|
|
|
|
+ *
|
|
|
|
+ * @param collection 需要转化的集合
|
|
|
|
+ * @param function 拼接方法
|
|
|
|
+ * @return 拼接后的list
|
|
|
|
+ */
|
|
|
|
+ public static <E> String join(Collection<E> collection, Function<E, String> function) {
|
|
|
|
+ return join(collection, function, StringUtils.SPACE);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 将collection拼接
|
|
|
|
+ *
|
|
|
|
+ * @param collection 需要转化的集合
|
|
|
|
+ * @param function 拼接方法
|
|
|
|
+ * @param delimiter 拼接符
|
|
|
|
+ * @return 拼接后的list
|
|
|
|
+ */
|
|
|
|
+ public static <E> String join(Collection<E> collection, Function<E, String> function, CharSequence delimiter) {
|
|
|
|
+ if (CollectionUtils.isEmpty(collection)) {
|
|
|
|
+ return StringUtils.EMPTY;
|
|
|
|
+ }
|
|
|
|
+ return collection.stream().map(function).filter(Objects::nonNull).collect(Collectors.joining(delimiter));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 将collection排序
|
|
|
|
+ *
|
|
|
|
+ * @param collection 需要转化的集合
|
|
|
|
+ * @param comparing 排序方法
|
|
|
|
+ * @return 排序后的list
|
|
|
|
+ */
|
|
|
|
+ public static <E> List<E> sorted(Collection<E> collection, Comparator<E> comparing) {
|
|
|
|
+ if (CollectionUtils.isEmpty(collection)) {
|
|
|
|
+ return new ArrayList<>();
|
|
|
|
+ }
|
|
|
|
+ return collection.stream().sorted(comparing).collect(Collectors.toList());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 将collection转化为类型不变的map<br>
|
|
|
|
+ * <B>{@code Collection<V> ----> Map<K,V>}</B>
|
|
|
|
+ *
|
|
|
|
+ * @param collection 需要转化的集合
|
|
|
|
+ * @param key V类型转化为K类型的lambda方法
|
|
|
|
+ * @param <V> collection中的泛型
|
|
|
|
+ * @param <K> map中的key类型
|
|
|
|
+ * @return 转化后的map
|
|
|
|
+ */
|
|
|
|
+ public static <V, K> Map<K, V> toIdentityMap(Collection<V> collection, Function<V, K> key) {
|
|
|
|
+ if (CollectionUtils.isEmpty(collection)) {
|
|
|
|
+ return new HashMap<>();
|
|
|
|
+ }
|
|
|
|
+ return collection.stream().collect(Collectors.toMap(key, Function.identity(), (l, r) -> l));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 将Collection转化为map(value类型与collection的泛型不同)<br>
|
|
|
|
+ * <B>{@code Collection<E> -----> Map<K,V> }</B>
|
|
|
|
+ *
|
|
|
|
+ * @param collection 需要转化的集合
|
|
|
|
+ * @param key E类型转化为K类型的lambda方法
|
|
|
|
+ * @param value E类型转化为V类型的lambda方法
|
|
|
|
+ * @param <E> collection中的泛型
|
|
|
|
+ * @param <K> map中的key类型
|
|
|
|
+ * @param <V> map中的value类型
|
|
|
|
+ * @return 转化后的map
|
|
|
|
+ */
|
|
|
|
+ public static <E, K, V> Map<K, V> toMap(Collection<E> collection, Function<E, K> key, Function<E, V> value) {
|
|
|
|
+ if (CollectionUtils.isEmpty(collection)) {
|
|
|
|
+ return new HashMap<>();
|
|
|
|
+ }
|
|
|
|
+ return collection.stream().collect(Collectors.toMap(key, value, (l, r) -> l));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 将collection按照规则(比如有相同的班级id)分类成map<br>
|
|
|
|
+ * <B>{@code Collection<E> -------> Map<K,List<E>> } </B>
|
|
|
|
+ *
|
|
|
|
+ * @param collection 需要分类的集合
|
|
|
|
+ * @param key 分类的规则
|
|
|
|
+ * @param <E> collection中的泛型
|
|
|
|
+ * @param <K> map中的key类型
|
|
|
|
+ * @return 分类后的map
|
|
|
|
+ */
|
|
|
|
+ public static <E, K> Map<K, List<E>> groupByKey(Collection<E> collection, Function<E, K> key) {
|
|
|
|
+ if (CollectionUtils.isEmpty(collection)) {
|
|
|
|
+ return new HashMap<>();
|
|
|
|
+ }
|
|
|
|
+ return collection.stream().collect(Collectors.groupingBy(key, LinkedHashMap::new, Collectors.toList()));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 将collection按照两个规则(比如有相同的年级id,班级id)分类成双层map<br>
|
|
|
|
+ * <B>{@code Collection<E> ---> Map<T,Map<U,List<E>>> } </B>
|
|
|
|
+ *
|
|
|
|
+ * @param collection 需要分类的集合
|
|
|
|
+ * @param key1 第一个分类的规则
|
|
|
|
+ * @param key2 第二个分类的规则
|
|
|
|
+ * @param <E> 集合元素类型
|
|
|
|
+ * @param <K> 第一个map中的key类型
|
|
|
|
+ * @param <U> 第二个map中的key类型
|
|
|
|
+ * @return 分类后的map
|
|
|
|
+ */
|
|
|
|
+ public static <E, K, U> Map<K, Map<U, List<E>>> groupBy2Key(Collection<E> collection, Function<E, K> key1,
|
|
|
|
+ Function<E, U> key2) {
|
|
|
|
+ if (CollectionUtils.isEmpty(collection)) {
|
|
|
|
+ return new HashMap<>();
|
|
|
|
+ }
|
|
|
|
+ return collection.stream().collect(Collectors.groupingBy(key1, LinkedHashMap::new,
|
|
|
|
+ Collectors.groupingBy(key2, LinkedHashMap::new, Collectors.toList())));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 将collection按照两个规则(比如有相同的年级id,班级id)分类成双层map<br>
|
|
|
|
+ * <B>{@code Collection<E> ---> Map<T,Map<U,E>> } </B>
|
|
|
|
+ *
|
|
|
|
+ * @param collection 需要分类的集合
|
|
|
|
+ * @param key1 第一个分类的规则
|
|
|
|
+ * @param key2 第二个分类的规则
|
|
|
|
+ * @param <T> 第一个map中的key类型
|
|
|
|
+ * @param <U> 第二个map中的key类型
|
|
|
|
+ * @param <E> collection中的泛型
|
|
|
|
+ * @return 分类后的map
|
|
|
|
+ */
|
|
|
|
+ public static <E, T, U> Map<T, Map<U, E>> group2Map(Collection<E> collection, Function<E, T> key1,
|
|
|
|
+ Function<E, U> key2) {
|
|
|
|
+ if (CollectionUtils.isEmpty(collection) || key1 == null || key2 == null) {
|
|
|
|
+ return new HashMap<>();
|
|
|
|
+ }
|
|
|
|
+ return collection.stream().collect(
|
|
|
|
+ Collectors.groupingBy(key1, LinkedHashMap::new, Collectors.toMap(key2, Function.identity(), (l, r) -> l)));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 将collection转化为List集合,但是两者的泛型不同<br>
|
|
|
|
+ * <B>{@code Collection<E> ------> List<T> } </B>
|
|
|
|
+ *
|
|
|
|
+ * @param collection 需要转化的集合
|
|
|
|
+ * @param function collection中的泛型转化为list泛型的lambda表达式
|
|
|
|
+ * @param <E> collection中的泛型
|
|
|
|
+ * @param <T> List中的泛型
|
|
|
|
+ * @return 转化后的list
|
|
|
|
+ */
|
|
|
|
+ public static <E, T> List<T> toList(Collection<E> collection, Function<E, T> function) {
|
|
|
|
+ if (CollectionUtils.isEmpty(collection)) {
|
|
|
|
+ return new ArrayList<>();
|
|
|
|
+ }
|
|
|
|
+ return collection.stream().map(function).filter(Objects::nonNull).collect(Collectors.toList());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 将collection转化为Set集合,但是两者的泛型不同<br>
|
|
|
|
+ * <B>{@code Collection<E> ------> Set<T> } </B>
|
|
|
|
+ *
|
|
|
|
+ * @param collection 需要转化的集合
|
|
|
|
+ * @param function collection中的泛型转化为set泛型的lambda表达式
|
|
|
|
+ * @param <E> collection中的泛型
|
|
|
|
+ * @param <T> Set中的泛型
|
|
|
|
+ * @return 转化后的Set
|
|
|
|
+ */
|
|
|
|
+ public static <E, T> Set<T> toSet(Collection<E> collection, Function<E, T> function) {
|
|
|
|
+ if (CollectionUtils.isEmpty(collection) || function == null) {
|
|
|
|
+ return new HashSet<>();
|
|
|
|
+ }
|
|
|
|
+ return collection.stream().map(function).filter(Objects::nonNull).collect(Collectors.toSet());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 合并两个相同key类型的map
|
|
|
|
+ *
|
|
|
|
+ * @param map1 第一个需要合并的 map
|
|
|
|
+ * @param map2 第二个需要合并的 map
|
|
|
|
+ * @param merge 合并的lambda,将key value1 value2合并成最终的类型,注意value可能为空的情况
|
|
|
|
+ * @param <K> map中的key类型
|
|
|
|
+ * @param <X> 第一个 map的value类型
|
|
|
|
+ * @param <Y> 第二个 map的value类型
|
|
|
|
+ * @param <V> 最终map的value类型
|
|
|
|
+ * @return 合并后的map
|
|
|
|
+ */
|
|
|
|
+ public static <K, X, Y, V> Map<K, V> merge(Map<K, X> map1, Map<K, Y> map2, BiFunction<X, Y, V> merge) {
|
|
|
|
+ if (MapUtils.isEmpty(map1) && MapUtils.isEmpty(map2)) {
|
|
|
|
+ return new HashMap<>();
|
|
|
|
+ }
|
|
|
|
+ else if (MapUtils.isEmpty(map1)) {
|
|
|
|
+ map1 = new HashMap<>();
|
|
|
|
+ }
|
|
|
|
+ else if (MapUtils.isEmpty(map2)) {
|
|
|
|
+ map2 = new HashMap<>();
|
|
|
|
+ }
|
|
|
|
+ Set<K> key = new HashSet<>();
|
|
|
|
+ key.addAll(map1.keySet());
|
|
|
|
+ key.addAll(map2.keySet());
|
|
|
|
+ Map<K, V> map = new HashMap<>();
|
|
|
|
+ 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;
|
|
|
|
+ }
|
|
|
|
+ /**
|
|
|
|
+ * 将 Set 切分成多个子集
|
|
|
|
+ * @param originalSet 原始 Set
|
|
|
|
+ * @param chunkSize 每个子集的大小
|
|
|
|
+ * @return 切分后的子集列表
|
|
|
|
+ */
|
|
|
|
+ public static List<List<String>> splitSet(Set<String> originalSet, int chunkSize) {
|
|
|
|
+ List<String> list = new ArrayList<>(originalSet);
|
|
|
|
+ return IntStream.range(0, (int) Math.ceil((double) list.size() / chunkSize))
|
|
|
|
+ .mapToObj(i -> list.subList(i * chunkSize, Math.min((i + 1) * chunkSize, list.size())))
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
+ }
|
|
|
|
+}
|