001/* 002 * Copyright 2024-2025, Warm-Flow (290631660@qq.com). 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.dromara.warm.flow.core.utils; 017 018 019import java.util.*; 020import java.util.function.BiFunction; 021import java.util.function.Function; 022import java.util.function.IntFunction; 023import java.util.function.Predicate; 024import java.util.stream.Collectors; 025 026/** 027 * stream 流工具类 028 * 029 * @author warm 030 */ 031public class StreamUtils { 032 033 private StreamUtils() { 034 } 035 036 /** 037 * 将collection过滤 038 * 039 * @param collection 需要转化的集合 040 * @param function 过滤方法 041 * @return 过滤后的list 042 */ 043 public static <E> List<E> filter(Collection<E> collection, Predicate<E> function) { 044 if (CollUtil.isEmpty(collection)) { 045 return new ArrayList<>(); 046 } 047 // 注意此处不要使用 .toList() 新语法 因为返回的是不可变List 会导致序列化问题 048 return collection.stream().filter(function).collect(Collectors.toList()); 049 } 050 051 /** 052 * 将collection拼接 053 * 054 * @param collection 需要转化的集合 055 * @param function 拼接方法 056 * @return 拼接后的list 057 */ 058 public static <E> String join(Collection<E> collection, Function<E, String> function) { 059 return join(collection, function, ","); 060 } 061 062 /** 063 * 将collection拼接 064 * 065 * @param collection 需要转化的集合 066 * @param function 拼接方法 067 * @param delimiter 拼接符 068 * @return 拼接后的list 069 */ 070 public static <E> String join(Collection<E> collection, Function<E, String> function, CharSequence delimiter) { 071 if (CollUtil.isEmpty(collection)) { 072 return ""; 073 } 074 return collection.stream().map(function).filter(Objects::nonNull).collect(Collectors.joining(delimiter)); 075 } 076 077 /** 078 * 将collection排序 079 * 080 * @param collection 需要转化的集合 081 * @param comparing 排序方法 082 * @return 排序后的list 083 */ 084 public static <E> List<E> sorted(Collection<E> collection, Comparator<E> comparing) { 085 if (CollUtil.isEmpty(collection)) { 086 return new ArrayList<>(); 087 } 088 // 注意此处不要使用 .toList() 新语法 因为返回的是不可变List 会导致序列化问题 089 return collection.stream().filter(Objects::nonNull).sorted(comparing).collect(Collectors.toList()); 090 } 091 092 /** 093 * 将collection转化为类型不变的map<br> 094 * <B>{@code Collection<V> ----> Map<K,V>}</B> 095 * 096 * @param collection 需要转化的集合 097 * @param key V类型转化为K类型的lambda方法 098 * @param <V> collection中的泛型 099 * @param <K> map中的key类型 100 * @return 转化后的map 101 */ 102 public static <V, K> Map<K, V> toIdentityMap(Collection<V> collection, Function<V, K> key) { 103 if (CollUtil.isEmpty(collection)) { 104 return new HashMap<>(); 105 } 106 return collection.stream().filter(Objects::nonNull) 107 .collect(Collectors.toMap(key, Function.identity(), (l, r) -> l)); 108 } 109 110 /** 111 * 将Collection转化为map(value类型与collection的泛型不同)<br> 112 * <B>{@code Collection<E> -----> Map<K,V> }</B> 113 * 114 * @param collection 需要转化的集合 115 * @param key E类型转化为K类型的lambda方法 116 * @param value E类型转化为V类型的lambda方法 117 * @param <E> collection中的泛型 118 * @param <K> map中的key类型 119 * @param <V> map中的value类型 120 * @return 转化后的map 121 */ 122 public static <E, K, V> Map<K, V> toMap(Collection<E> collection, Function<E, K> key, Function<E, V> value) { 123 if (CollUtil.isEmpty(collection)) { 124 return new HashMap<>(); 125 } 126 return collection.stream().filter(Objects::nonNull).collect(Collectors.toMap(key, value, (l, r) -> l)); 127 } 128 129 /** 130 * 将collection按照规则(比如有相同的班级id)分类成map<br> 131 * <B>{@code Collection<E> -------> Map<K,List<E>> } </B> 132 * 133 * @param collection 需要分类的集合 134 * @param key 分类的规则 135 * @param <E> collection中的泛型 136 * @param <K> map中的key类型 137 * @return 分类后的map 138 */ 139 public static <E, K> Map<K, List<E>> groupByKey(Collection<E> collection, Function<E, K> key) { 140 if (CollUtil.isEmpty(collection)) { 141 return new HashMap<>(); 142 } 143 return collection.stream().filter(Objects::nonNull) 144 .collect(Collectors.groupingBy(key, LinkedHashMap::new, Collectors.toList())); 145 } 146 147 /** 148 * 将collection按照规则(比如有相同的班级id)分类成map<br> 149 * <B>{@code Collection<E> -------> Map<K,List<E>> } </B> 150 * 151 * @param collection 需要分类的集合 152 * @param key 分类的规则 153 * @param <E> collection中的泛型 154 * @param <K> map中的key类型 155 * @return 分类后的map 156 */ 157 public static <T, E, K> Map<K, List<E>> groupByKeyFilter(Predicate<E> predicate, Collection<E> collection, Function<E, K> key) { 158 if (CollUtil.isEmpty(collection)) { 159 return new HashMap<>(); 160 } 161 return collection.stream().filter(predicate) 162 .collect(Collectors.groupingBy(key, LinkedHashMap::new, Collectors.toList())); 163 } 164 165 /** 166 * 将collection按照两个规则(比如有相同的年级id,班级id)分类成双层map<br> 167 * <B>{@code Collection<E> ---> Map<T,Map<U,List<E>>> } </B> 168 * 169 * @param collection 需要分类的集合 170 * @param key1 第一个分类的规则 171 * @param key2 第二个分类的规则 172 * @param <E> 集合元素类型 173 * @param <K> 第一个map中的key类型 174 * @param <U> 第二个map中的key类型 175 * @return 分类后的map 176 */ 177 public static <E, K, U> Map<K, Map<U, List<E>>> groupBy2Key(Collection<E> collection, Function<E, K> key1, 178 Function<E, U> key2) { 179 if (CollUtil.isEmpty(collection)) { 180 return new HashMap<>(); 181 } 182 return collection.stream().filter(Objects::nonNull).collect(Collectors.groupingBy(key1, LinkedHashMap::new, 183 Collectors.groupingBy(key2, LinkedHashMap::new, Collectors.toList()))); 184 } 185 186 /** 187 * 将collection按照两个规则(比如有相同的年级id,班级id)分类成双层map<br> 188 * <B>{@code Collection<E> ---> Map<T,Map<U,E>> } </B> 189 * 190 * @param collection 需要分类的集合 191 * @param key1 第一个分类的规则 192 * @param key2 第二个分类的规则 193 * @param <T> 第一个map中的key类型 194 * @param <U> 第二个map中的key类型 195 * @param <E> collection中的泛型 196 * @return 分类后的map 197 */ 198 public static <E, T, U> Map<T, Map<U, E>> group2Map(Collection<E> collection, Function<E, T> key1, 199 Function<E, U> key2) { 200 if (CollUtil.isEmpty(collection) || key1 == null || key2 == null) { 201 return new HashMap<>(); 202 } 203 return collection.stream().filter(Objects::nonNull).collect( 204 Collectors.groupingBy(key1, LinkedHashMap::new, Collectors.toMap(key2, Function.identity(), (l, r) -> l))); 205 } 206 207 /** 208 * 将collection转化为List集合,但是两者的泛型不同<br> 209 * <B>{@code Collection<E> ------> List<T> } </B> 210 * 211 * @param collection 需要转化的集合 212 * @param function collection中的泛型转化为list泛型的lambda表达式 213 * @param <E> collection中的泛型 214 * @param <T> List中的泛型 215 * @return 转化后的list 216 */ 217 public static <E, T> List<T> toList(Collection<E> collection, Function<E, T> function) { 218 if (CollUtil.isEmpty(collection)) { 219 return new ArrayList<>(); 220 } 221 return collection.stream().map(function).filter(Objects::nonNull) 222 // 注意此处不要使用 .toList() 新语法 因为返回的是不可变List 会导致序列化问题 223 .collect(Collectors.toList()); 224 } 225 226 /** 227 * 将collection转化为Set集合,但是两者的泛型不同<br> 228 * <B>{@code Collection<E> ------> Set<T> } </B> 229 * 230 * @param collection 需要转化的集合 231 * @param function collection中的泛型转化为set泛型的lambda表达式 232 * @param <E> collection中的泛型 233 * @param <T> Set中的泛型 234 * @return 转化后的Set 235 */ 236 public static <E, T> Set<T> toSet(Collection<E> collection, Function<E, T> function) { 237 if (CollUtil.isEmpty(collection) || function == null) { 238 return new HashSet<>(); 239 } 240 return collection.stream().map(function).filter(Objects::nonNull).collect(Collectors.toSet()); 241 } 242 243 /** 244 * 将collection转化为List集合,但是两者的泛型不同<br> 245 * <B>{@code Collection<E> ------> List<T> } </B> 246 * 247 * @param collection 需要转化的集合 248 * @param generator collection中的泛型转化为list泛型的lambda表达式 249 * @param <E> collection中的泛型 250 * @return 转化后的list 251 */ 252 public static <E> E[] toArray(Collection<E> collection, IntFunction<E[]> generator) { 253 if (CollUtil.isEmpty(collection)) { 254 return generator.apply(0); 255 } 256 return collection.stream().toArray(generator); 257 } 258 259 /** 260 * 合并两个相同key类型的map 261 * 262 * @param map1 第一个需要合并的 map 263 * @param map2 第二个需要合并的 map 264 * @param merge 合并的lambda,将key value1 value2合并成最终的类型,注意value可能为空的情况 265 * @param <K> map中的key类型 266 * @param <X> 第一个 map的value类型 267 * @param <Y> 第二个 map的value类型 268 * @param <V> 最终map的value类型 269 * @return 合并后的map 270 */ 271 public static <K, X, Y, V> Map<K, V> merge(Map<K, X> map1, Map<K, Y> map2, BiFunction<X, Y, V> merge) { 272 if (MapUtil.isEmpty(map1) && MapUtil.isEmpty(map2)) { 273 return new HashMap<>(); 274 } else if (MapUtil.isEmpty(map1)) { 275 map1 = new HashMap<>(); 276 } else if (MapUtil.isEmpty(map2)) { 277 map2 = new HashMap<>(); 278 } 279 Set<K> key = new HashSet<>(); 280 key.addAll(map1.keySet()); 281 key.addAll(map2.keySet()); 282 Map<K, V> map = new HashMap<>(); 283 for (K t : key) { 284 X x = map1.get(t); 285 Y y = map2.get(t); 286 V z = merge.apply(x, y); 287 if (z != null) { 288 map.put(t, z); 289 } 290 } 291 return map; 292 } 293 294}