StreamUtils.java 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. package com.ruoyi.common.utils;
  2. import cn.hutool.core.collection.CollUtil;
  3. import cn.hutool.core.map.MapUtil;
  4. import lombok.AccessLevel;
  5. import lombok.NoArgsConstructor;
  6. import java.util.*;
  7. import java.util.function.BiFunction;
  8. import java.util.function.Function;
  9. import java.util.function.Predicate;
  10. import java.util.stream.Collectors;
  11. /**
  12. * stream 流工具类
  13. *
  14. * @author Lion Li
  15. */
  16. @NoArgsConstructor(access = AccessLevel.PRIVATE)
  17. public class StreamUtils {
  18. /**
  19. * 将collection过滤
  20. *
  21. * @param collection 需要转化的集合
  22. * @param function 过滤方法
  23. * @return 过滤后的list
  24. */
  25. public static <E> List<E> filter(Collection<E> collection, Predicate<E> function) {
  26. if (CollUtil.isEmpty(collection)) {
  27. return CollUtil.newArrayList();
  28. }
  29. return collection.stream().filter(function).collect(Collectors.toList());
  30. }
  31. /**
  32. * 将collection拼接
  33. *
  34. * @param collection 需要转化的集合
  35. * @param function 拼接方法
  36. * @return 拼接后的list
  37. */
  38. public static <E> String join(Collection<E> collection, Function<E, String> function) {
  39. return join(collection, function, ",");
  40. }
  41. /**
  42. * 将collection拼接
  43. *
  44. * @param collection 需要转化的集合
  45. * @param function 拼接方法
  46. * @param delimiter 拼接符
  47. * @return 拼接后的list
  48. */
  49. public static <E> String join(Collection<E> collection, Function<E, String> function, CharSequence delimiter) {
  50. if (CollUtil.isEmpty(collection)) {
  51. return StringUtils.EMPTY;
  52. }
  53. return collection.stream().map(function).filter(Objects::nonNull).collect(Collectors.joining(delimiter));
  54. }
  55. /**
  56. * 将collection排序
  57. *
  58. * @param collection 需要转化的集合
  59. * @param comparing 排序方法
  60. * @return 排序后的list
  61. */
  62. public static <E> List<E> sorted(Collection<E> collection, Comparator<E> comparing) {
  63. if (CollUtil.isEmpty(collection)) {
  64. return CollUtil.newArrayList();
  65. }
  66. return collection.stream().sorted(comparing).collect(Collectors.toList());
  67. }
  68. /**
  69. * 将collection转化为类型不变的map<br>
  70. * <B>{@code Collection<V> ----> Map<K,V>}</B>
  71. *
  72. * @param collection 需要转化的集合
  73. * @param key V类型转化为K类型的lambda方法
  74. * @param <V> collection中的泛型
  75. * @param <K> map中的key类型
  76. * @return 转化后的map
  77. */
  78. public static <V, K> Map<K, V> toIdentityMap(Collection<V> collection, Function<V, K> key) {
  79. if (CollUtil.isEmpty(collection)) {
  80. return MapUtil.newHashMap();
  81. }
  82. return collection.stream().collect(Collectors.toMap(key, Function.identity(), (l, r) -> l));
  83. }
  84. /**
  85. * 将Collection转化为map(value类型与collection的泛型不同)<br>
  86. * <B>{@code Collection<E> -----> Map<K,V> }</B>
  87. *
  88. * @param collection 需要转化的集合
  89. * @param key E类型转化为K类型的lambda方法
  90. * @param value E类型转化为V类型的lambda方法
  91. * @param <E> collection中的泛型
  92. * @param <K> map中的key类型
  93. * @param <V> map中的value类型
  94. * @return 转化后的map
  95. */
  96. public static <E, K, V> Map<K, V> toMap(Collection<E> collection, Function<E, K> key, Function<E, V> value) {
  97. if (CollUtil.isEmpty(collection)) {
  98. return MapUtil.newHashMap();
  99. }
  100. return collection.stream().collect(Collectors.toMap(key, value, (l, r) -> l));
  101. }
  102. /**
  103. * 将collection按照规则(比如有相同的班级id)分类成map<br>
  104. * <B>{@code Collection<E> -------> Map<K,List<E>> } </B>
  105. *
  106. * @param collection 需要分类的集合
  107. * @param key 分类的规则
  108. * @param <E> collection中的泛型
  109. * @param <K> map中的key类型
  110. * @return 分类后的map
  111. */
  112. public static <E, K> Map<K, List<E>> groupByKey(Collection<E> collection, Function<E, K> key) {
  113. if (CollUtil.isEmpty(collection)) {
  114. return MapUtil.newHashMap();
  115. }
  116. return collection
  117. .stream()
  118. .collect(Collectors.groupingBy(key, LinkedHashMap::new, Collectors.toList()));
  119. }
  120. /**
  121. * 将collection按照两个规则(比如有相同的年级id,班级id)分类成双层map<br>
  122. * <B>{@code Collection<E> ---> Map<T,Map<U,List<E>>> } </B>
  123. *
  124. * @param collection 需要分类的集合
  125. * @param key1 第一个分类的规则
  126. * @param key2 第二个分类的规则
  127. * @param <E> 集合元素类型
  128. * @param <K> 第一个map中的key类型
  129. * @param <U> 第二个map中的key类型
  130. * @return 分类后的map
  131. */
  132. public static <E, K, U> Map<K, Map<U, List<E>>> groupBy2Key(Collection<E> collection, Function<E, K> key1, Function<E, U> key2) {
  133. if (CollUtil.isEmpty(collection)) {
  134. return MapUtil.newHashMap();
  135. }
  136. return collection
  137. .stream()
  138. .collect(Collectors.groupingBy(key1, LinkedHashMap::new, Collectors.groupingBy(key2, LinkedHashMap::new, Collectors.toList())));
  139. }
  140. /**
  141. * 将collection按照两个规则(比如有相同的年级id,班级id)分类成双层map<br>
  142. * <B>{@code Collection<E> ---> Map<T,Map<U,E>> } </B>
  143. *
  144. * @param collection 需要分类的集合
  145. * @param key1 第一个分类的规则
  146. * @param key2 第二个分类的规则
  147. * @param <T> 第一个map中的key类型
  148. * @param <U> 第二个map中的key类型
  149. * @param <E> collection中的泛型
  150. * @return 分类后的map
  151. */
  152. public static <E, T, U> Map<T, Map<U, E>> group2Map(Collection<E> collection, Function<E, T> key1, Function<E, U> key2) {
  153. if (CollUtil.isEmpty(collection) || key1 == null || key2 == null) {
  154. return MapUtil.newHashMap();
  155. }
  156. return collection
  157. .stream()
  158. .collect(Collectors.groupingBy(key1, LinkedHashMap::new, Collectors.toMap(key2, Function.identity(), (l, r) -> l)));
  159. }
  160. /**
  161. * 将collection转化为List集合,但是两者的泛型不同<br>
  162. * <B>{@code Collection<E> ------> List<T> } </B>
  163. *
  164. * @param collection 需要转化的集合
  165. * @param function collection中的泛型转化为list泛型的lambda表达式
  166. * @param <E> collection中的泛型
  167. * @param <T> List中的泛型
  168. * @return 转化后的list
  169. */
  170. public static <E, T> List<T> toList(Collection<E> collection, Function<E, T> function) {
  171. if (CollUtil.isEmpty(collection)) {
  172. return CollUtil.newArrayList();
  173. }
  174. return collection
  175. .stream()
  176. .map(function)
  177. .filter(Objects::nonNull)
  178. .collect(Collectors.toList());
  179. }
  180. /**
  181. * 将collection转化为Set集合,但是两者的泛型不同<br>
  182. * <B>{@code Collection<E> ------> Set<T> } </B>
  183. *
  184. * @param collection 需要转化的集合
  185. * @param function collection中的泛型转化为set泛型的lambda表达式
  186. * @param <E> collection中的泛型
  187. * @param <T> Set中的泛型
  188. * @return 转化后的Set
  189. */
  190. public static <E, T> Set<T> toSet(Collection<E> collection, Function<E, T> function) {
  191. if (CollUtil.isEmpty(collection) || function == null) {
  192. return CollUtil.newHashSet();
  193. }
  194. return collection
  195. .stream()
  196. .map(function)
  197. .filter(Objects::nonNull)
  198. .collect(Collectors.toSet());
  199. }
  200. /**
  201. * 合并两个相同key类型的map
  202. *
  203. * @param map1 第一个需要合并的 map
  204. * @param map2 第二个需要合并的 map
  205. * @param merge 合并的lambda,将key value1 value2合并成最终的类型,注意value可能为空的情况
  206. * @param <K> map中的key类型
  207. * @param <X> 第一个 map的value类型
  208. * @param <Y> 第二个 map的value类型
  209. * @param <V> 最终map的value类型
  210. * @return 合并后的map
  211. */
  212. public static <K, X, Y, V> Map<K, V> merge(Map<K, X> map1, Map<K, Y> map2, BiFunction<X, Y, V> merge) {
  213. if (MapUtil.isEmpty(map1) && MapUtil.isEmpty(map2)) {
  214. return MapUtil.newHashMap();
  215. } else if (MapUtil.isEmpty(map1)) {
  216. map1 = MapUtil.newHashMap();
  217. } else if (MapUtil.isEmpty(map2)) {
  218. map2 = MapUtil.newHashMap();
  219. }
  220. Set<K> key = new HashSet<>();
  221. key.addAll(map1.keySet());
  222. key.addAll(map2.keySet());
  223. Map<K, V> map = new HashMap<>();
  224. for (K t : key) {
  225. X x = map1.get(t);
  226. Y y = map2.get(t);
  227. V z = merge.apply(x, y);
  228. if (z != null) {
  229. map.put(t, z);
  230. }
  231. }
  232. return map;
  233. }
  234. }