提交 | 用户 | 时间
|
e7c126
|
1 |
package com.iailab.framework.common.util.collection; |
H |
2 |
|
|
3 |
import cn.hutool.core.collection.CollUtil; |
|
4 |
import cn.hutool.core.collection.CollectionUtil; |
|
5 |
import cn.hutool.core.util.ArrayUtil; |
|
6 |
import com.google.common.collect.ImmutableMap; |
bb2880
|
7 |
import com.iailab.framework.common.pojo.PageResult; |
e7c126
|
8 |
|
H |
9 |
import java.util.*; |
|
10 |
import java.util.function.*; |
|
11 |
import java.util.stream.Collectors; |
|
12 |
import java.util.stream.Stream; |
|
13 |
|
|
14 |
import static java.util.Arrays.asList; |
|
15 |
|
|
16 |
/** |
|
17 |
* Collection 工具类 |
|
18 |
* |
|
19 |
* @author iailab |
|
20 |
*/ |
|
21 |
public class CollectionUtils { |
|
22 |
|
|
23 |
public static boolean containsAny(Object source, Object... targets) { |
|
24 |
return asList(targets).contains(source); |
|
25 |
} |
|
26 |
|
|
27 |
public static boolean isAnyEmpty(Collection<?>... collections) { |
|
28 |
return Arrays.stream(collections).anyMatch(CollectionUtil::isEmpty); |
|
29 |
} |
|
30 |
|
|
31 |
public static <T> boolean anyMatch(Collection<T> from, Predicate<T> predicate) { |
|
32 |
return from.stream().anyMatch(predicate); |
|
33 |
} |
|
34 |
|
|
35 |
public static <T> List<T> filterList(Collection<T> from, Predicate<T> predicate) { |
|
36 |
if (CollUtil.isEmpty(from)) { |
|
37 |
return new ArrayList<>(); |
|
38 |
} |
|
39 |
return from.stream().filter(predicate).collect(Collectors.toList()); |
|
40 |
} |
|
41 |
|
|
42 |
public static <T, R> List<T> distinct(Collection<T> from, Function<T, R> keyMapper) { |
|
43 |
if (CollUtil.isEmpty(from)) { |
|
44 |
return new ArrayList<>(); |
|
45 |
} |
|
46 |
return distinct(from, keyMapper, (t1, t2) -> t1); |
|
47 |
} |
|
48 |
|
|
49 |
public static <T, R> List<T> distinct(Collection<T> from, Function<T, R> keyMapper, BinaryOperator<T> cover) { |
|
50 |
if (CollUtil.isEmpty(from)) { |
|
51 |
return new ArrayList<>(); |
|
52 |
} |
|
53 |
return new ArrayList<>(convertMap(from, keyMapper, Function.identity(), cover).values()); |
|
54 |
} |
|
55 |
|
|
56 |
public static <T, U> List<U> convertList(T[] from, Function<T, U> func) { |
|
57 |
if (ArrayUtil.isEmpty(from)) { |
|
58 |
return new ArrayList<>(); |
|
59 |
} |
|
60 |
return convertList(Arrays.asList(from), func); |
|
61 |
} |
|
62 |
|
|
63 |
public static <T, U> List<U> convertList(Collection<T> from, Function<T, U> func) { |
|
64 |
if (CollUtil.isEmpty(from)) { |
|
65 |
return new ArrayList<>(); |
|
66 |
} |
|
67 |
return from.stream().map(func).filter(Objects::nonNull).collect(Collectors.toList()); |
|
68 |
} |
|
69 |
|
|
70 |
public static <T, U> List<U> convertList(Collection<T> from, Function<T, U> func, Predicate<T> filter) { |
|
71 |
if (CollUtil.isEmpty(from)) { |
|
72 |
return new ArrayList<>(); |
|
73 |
} |
|
74 |
return from.stream().filter(filter).map(func).filter(Objects::nonNull).collect(Collectors.toList()); |
bb2880
|
75 |
} |
H |
76 |
|
|
77 |
public static <T, U> PageResult<U> convertPage(PageResult<T> from, Function<T, U> func) { |
|
78 |
if (ArrayUtil.isEmpty(from)) { |
|
79 |
return new PageResult<>(from.getTotal()); |
|
80 |
} |
|
81 |
return new PageResult<>(convertList(from.getList(), func), from.getTotal()); |
e7c126
|
82 |
} |
H |
83 |
|
|
84 |
public static <T, U> List<U> convertListByFlatMap(Collection<T> from, |
|
85 |
Function<T, ? extends Stream<? extends U>> func) { |
|
86 |
if (CollUtil.isEmpty(from)) { |
|
87 |
return new ArrayList<>(); |
|
88 |
} |
|
89 |
return from.stream().filter(Objects::nonNull).flatMap(func).filter(Objects::nonNull).collect(Collectors.toList()); |
|
90 |
} |
|
91 |
|
|
92 |
public static <T, U, R> List<R> convertListByFlatMap(Collection<T> from, |
|
93 |
Function<? super T, ? extends U> mapper, |
|
94 |
Function<U, ? extends Stream<? extends R>> func) { |
|
95 |
if (CollUtil.isEmpty(from)) { |
|
96 |
return new ArrayList<>(); |
|
97 |
} |
|
98 |
return from.stream().map(mapper).filter(Objects::nonNull).flatMap(func).filter(Objects::nonNull).collect(Collectors.toList()); |
|
99 |
} |
|
100 |
|
|
101 |
public static <K, V> List<V> mergeValuesFromMap(Map<K, List<V>> map) { |
|
102 |
return map.values() |
|
103 |
.stream() |
|
104 |
.flatMap(List::stream) |
|
105 |
.collect(Collectors.toList()); |
|
106 |
} |
|
107 |
|
|
108 |
public static <T> Set<T> convertSet(Collection<T> from) { |
|
109 |
return convertSet(from, v -> v); |
|
110 |
} |
|
111 |
|
|
112 |
public static <T, U> Set<U> convertSet(Collection<T> from, Function<T, U> func) { |
|
113 |
if (CollUtil.isEmpty(from)) { |
|
114 |
return new HashSet<>(); |
|
115 |
} |
|
116 |
return from.stream().map(func).filter(Objects::nonNull).collect(Collectors.toSet()); |
|
117 |
} |
|
118 |
|
|
119 |
public static <T, U> Set<U> convertSet(Collection<T> from, Function<T, U> func, Predicate<T> filter) { |
|
120 |
if (CollUtil.isEmpty(from)) { |
|
121 |
return new HashSet<>(); |
|
122 |
} |
|
123 |
return from.stream().filter(filter).map(func).filter(Objects::nonNull).collect(Collectors.toSet()); |
|
124 |
} |
|
125 |
|
|
126 |
public static <T, K> Map<K, T> convertMapByFilter(Collection<T> from, Predicate<T> filter, Function<T, K> keyFunc) { |
|
127 |
if (CollUtil.isEmpty(from)) { |
|
128 |
return new HashMap<>(); |
|
129 |
} |
|
130 |
return from.stream().filter(filter).collect(Collectors.toMap(keyFunc, v -> v)); |
|
131 |
} |
|
132 |
|
|
133 |
public static <T, U> Set<U> convertSetByFlatMap(Collection<T> from, |
|
134 |
Function<T, ? extends Stream<? extends U>> func) { |
|
135 |
if (CollUtil.isEmpty(from)) { |
|
136 |
return new HashSet<>(); |
|
137 |
} |
|
138 |
return from.stream().filter(Objects::nonNull).flatMap(func).filter(Objects::nonNull).collect(Collectors.toSet()); |
|
139 |
} |
|
140 |
|
|
141 |
public static <T, U, R> Set<R> convertSetByFlatMap(Collection<T> from, |
|
142 |
Function<? super T, ? extends U> mapper, |
|
143 |
Function<U, ? extends Stream<? extends R>> func) { |
|
144 |
if (CollUtil.isEmpty(from)) { |
|
145 |
return new HashSet<>(); |
|
146 |
} |
|
147 |
return from.stream().map(mapper).filter(Objects::nonNull).flatMap(func).filter(Objects::nonNull).collect(Collectors.toSet()); |
|
148 |
} |
|
149 |
|
|
150 |
public static <T, K> Map<K, T> convertMap(Collection<T> from, Function<T, K> keyFunc) { |
|
151 |
if (CollUtil.isEmpty(from)) { |
|
152 |
return new HashMap<>(); |
|
153 |
} |
|
154 |
return convertMap(from, keyFunc, Function.identity()); |
|
155 |
} |
|
156 |
|
|
157 |
public static <T, K> Map<K, T> convertMap(Collection<T> from, Function<T, K> keyFunc, Supplier<? extends Map<K, T>> supplier) { |
|
158 |
if (CollUtil.isEmpty(from)) { |
|
159 |
return supplier.get(); |
|
160 |
} |
|
161 |
return convertMap(from, keyFunc, Function.identity(), supplier); |
|
162 |
} |
|
163 |
|
|
164 |
public static <T, K, V> Map<K, V> convertMap(Collection<T> from, Function<T, K> keyFunc, Function<T, V> valueFunc) { |
|
165 |
if (CollUtil.isEmpty(from)) { |
|
166 |
return new HashMap<>(); |
|
167 |
} |
|
168 |
return convertMap(from, keyFunc, valueFunc, (v1, v2) -> v1); |
|
169 |
} |
|
170 |
|
|
171 |
public static <T, K, V> Map<K, V> convertMap(Collection<T> from, Function<T, K> keyFunc, Function<T, V> valueFunc, BinaryOperator<V> mergeFunction) { |
|
172 |
if (CollUtil.isEmpty(from)) { |
|
173 |
return new HashMap<>(); |
|
174 |
} |
|
175 |
return convertMap(from, keyFunc, valueFunc, mergeFunction, HashMap::new); |
|
176 |
} |
|
177 |
|
|
178 |
public static <T, K, V> Map<K, V> convertMap(Collection<T> from, Function<T, K> keyFunc, Function<T, V> valueFunc, Supplier<? extends Map<K, V>> supplier) { |
|
179 |
if (CollUtil.isEmpty(from)) { |
|
180 |
return supplier.get(); |
|
181 |
} |
|
182 |
return convertMap(from, keyFunc, valueFunc, (v1, v2) -> v1, supplier); |
|
183 |
} |
|
184 |
|
|
185 |
public static <T, K, V> Map<K, V> convertMap(Collection<T> from, Function<T, K> keyFunc, Function<T, V> valueFunc, BinaryOperator<V> mergeFunction, Supplier<? extends Map<K, V>> supplier) { |
|
186 |
if (CollUtil.isEmpty(from)) { |
|
187 |
return new HashMap<>(); |
|
188 |
} |
|
189 |
return from.stream().collect(Collectors.toMap(keyFunc, valueFunc, mergeFunction, supplier)); |
|
190 |
} |
|
191 |
|
|
192 |
public static <T, K> Map<K, List<T>> convertMultiMap(Collection<T> from, Function<T, K> keyFunc) { |
|
193 |
if (CollUtil.isEmpty(from)) { |
|
194 |
return new HashMap<>(); |
|
195 |
} |
|
196 |
return from.stream().collect(Collectors.groupingBy(keyFunc, Collectors.mapping(t -> t, Collectors.toList()))); |
|
197 |
} |
|
198 |
|
|
199 |
public static <T, K, V> Map<K, List<V>> convertMultiMap(Collection<T> from, Function<T, K> keyFunc, Function<T, V> valueFunc) { |
|
200 |
if (CollUtil.isEmpty(from)) { |
|
201 |
return new HashMap<>(); |
|
202 |
} |
|
203 |
return from.stream() |
|
204 |
.collect(Collectors.groupingBy(keyFunc, Collectors.mapping(valueFunc, Collectors.toList()))); |
|
205 |
} |
|
206 |
|
|
207 |
// 暂时没想好名字,先以 2 结尾噶 |
|
208 |
public static <T, K, V> Map<K, Set<V>> convertMultiMap2(Collection<T> from, Function<T, K> keyFunc, Function<T, V> valueFunc) { |
|
209 |
if (CollUtil.isEmpty(from)) { |
|
210 |
return new HashMap<>(); |
|
211 |
} |
|
212 |
return from.stream().collect(Collectors.groupingBy(keyFunc, Collectors.mapping(valueFunc, Collectors.toSet()))); |
|
213 |
} |
|
214 |
|
|
215 |
public static <T, K> Map<K, T> convertImmutableMap(Collection<T> from, Function<T, K> keyFunc) { |
|
216 |
if (CollUtil.isEmpty(from)) { |
|
217 |
return Collections.emptyMap(); |
|
218 |
} |
|
219 |
ImmutableMap.Builder<K, T> builder = ImmutableMap.builder(); |
|
220 |
from.forEach(item -> builder.put(keyFunc.apply(item), item)); |
|
221 |
return builder.build(); |
|
222 |
} |
|
223 |
|
|
224 |
/** |
|
225 |
* 对比老、新两个列表,找出新增、修改、删除的数据 |
|
226 |
* |
|
227 |
* @param oldList 老列表 |
|
228 |
* @param newList 新列表 |
|
229 |
* @param sameFunc 对比函数,返回 true 表示相同,返回 false 表示不同 |
|
230 |
* 注意,same 是通过每个元素的“标识”,判断它们是不是同一个数据 |
|
231 |
* @return [新增列表、修改列表、删除列表] |
|
232 |
*/ |
|
233 |
public static <T> List<List<T>> diffList(Collection<T> oldList, Collection<T> newList, |
|
234 |
BiFunction<T, T, Boolean> sameFunc) { |
|
235 |
List<T> createList = new LinkedList<>(newList); // 默认都认为是新增的,后续会进行移除 |
|
236 |
List<T> updateList = new ArrayList<>(); |
|
237 |
List<T> deleteList = new ArrayList<>(); |
|
238 |
|
|
239 |
// 通过以 oldList 为主遍历,找出 updateList 和 deleteList |
|
240 |
for (T oldObj : oldList) { |
|
241 |
// 1. 寻找是否有匹配的 |
|
242 |
T foundObj = null; |
|
243 |
for (Iterator<T> iterator = createList.iterator(); iterator.hasNext(); ) { |
|
244 |
T newObj = iterator.next(); |
|
245 |
// 1.1 不匹配,则直接跳过 |
|
246 |
if (!sameFunc.apply(oldObj, newObj)) { |
|
247 |
continue; |
|
248 |
} |
|
249 |
// 1.2 匹配,则移除,并结束寻找 |
|
250 |
iterator.remove(); |
|
251 |
foundObj = newObj; |
|
252 |
break; |
|
253 |
} |
|
254 |
// 2. 匹配添加到 updateList;不匹配则添加到 deleteList 中 |
|
255 |
if (foundObj != null) { |
|
256 |
updateList.add(foundObj); |
|
257 |
} else { |
|
258 |
deleteList.add(oldObj); |
|
259 |
} |
|
260 |
} |
|
261 |
return asList(createList, updateList, deleteList); |
|
262 |
} |
|
263 |
|
|
264 |
public static boolean containsAny(Collection<?> source, Collection<?> candidates) { |
|
265 |
return org.springframework.util.CollectionUtils.containsAny(source, candidates); |
|
266 |
} |
|
267 |
|
|
268 |
public static <T> T getFirst(List<T> from) { |
|
269 |
return !CollectionUtil.isEmpty(from) ? from.get(0) : null; |
|
270 |
} |
|
271 |
|
|
272 |
public static <T> T findFirst(Collection<T> from, Predicate<T> predicate) { |
|
273 |
return findFirst(from, predicate, Function.identity()); |
|
274 |
} |
|
275 |
|
|
276 |
public static <T, U> U findFirst(Collection<T> from, Predicate<T> predicate, Function<T, U> func) { |
|
277 |
if (CollUtil.isEmpty(from)) { |
|
278 |
return null; |
|
279 |
} |
|
280 |
return from.stream().filter(predicate).findFirst().map(func).orElse(null); |
|
281 |
} |
|
282 |
|
|
283 |
public static <T, V extends Comparable<? super V>> V getMaxValue(Collection<T> from, Function<T, V> valueFunc) { |
|
284 |
if (CollUtil.isEmpty(from)) { |
|
285 |
return null; |
|
286 |
} |
|
287 |
assert !from.isEmpty(); // 断言,避免告警 |
|
288 |
T t = from.stream().max(Comparator.comparing(valueFunc)).get(); |
|
289 |
return valueFunc.apply(t); |
|
290 |
} |
|
291 |
|
|
292 |
public static <T, V extends Comparable<? super V>> V getMinValue(List<T> from, Function<T, V> valueFunc) { |
|
293 |
if (CollUtil.isEmpty(from)) { |
|
294 |
return null; |
|
295 |
} |
|
296 |
assert from.size() > 0; // 断言,避免告警 |
|
297 |
T t = from.stream().min(Comparator.comparing(valueFunc)).get(); |
|
298 |
return valueFunc.apply(t); |
|
299 |
} |
|
300 |
|
bb2880
|
301 |
public static <T, V extends Comparable<? super V>> T getMinObject(List<T> from, Function<T, V> valueFunc) { |
H |
302 |
if (CollUtil.isEmpty(from)) { |
|
303 |
return null; |
|
304 |
} |
|
305 |
assert from.size() > 0; // 断言,避免告警 |
|
306 |
return from.stream().min(Comparator.comparing(valueFunc)).get(); |
|
307 |
} |
|
308 |
|
|
309 |
public static <T, V extends Comparable<? super V>> V getSumValue(Collection<T> from, Function<T, V> valueFunc, |
e7c126
|
310 |
BinaryOperator<V> accumulator) { |
H |
311 |
return getSumValue(from, valueFunc, accumulator, null); |
|
312 |
} |
|
313 |
|
|
314 |
public static <T, V extends Comparable<? super V>> V getSumValue(Collection<T> from, Function<T, V> valueFunc, |
|
315 |
BinaryOperator<V> accumulator, V defaultValue) { |
|
316 |
if (CollUtil.isEmpty(from)) { |
|
317 |
return defaultValue; |
|
318 |
} |
|
319 |
assert !from.isEmpty(); // 断言,避免告警 |
|
320 |
return from.stream().map(valueFunc).filter(Objects::nonNull).reduce(accumulator).orElse(defaultValue); |
|
321 |
} |
|
322 |
|
|
323 |
public static <T> void addIfNotNull(Collection<T> coll, T item) { |
|
324 |
if (item == null) { |
|
325 |
return; |
|
326 |
} |
|
327 |
coll.add(item); |
|
328 |
} |
|
329 |
|
|
330 |
public static <T> Collection<T> singleton(T obj) { |
|
331 |
return obj == null ? Collections.emptyList() : Collections.singleton(obj); |
|
332 |
} |
|
333 |
|
|
334 |
public static <T> List<T> newArrayList(List<List<T>> list) { |
bb2880
|
335 |
return list.stream().filter(Objects::nonNull).flatMap(Collection::stream).collect(Collectors.toList()); |
e7c126
|
336 |
} |
H |
337 |
|
|
338 |
} |