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