陈昶聿
昨天 16b3634770a117c67433304d939ac3d5bd6a6ed4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package com.ruoyi.common.utils;
 
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
 
public class ArrayListUtils {
 
    /**
     * 根据ID将两个List拆分为:仅List1独有、仅List2独有、两者共有
     *
     * @param list1 列表1
     * @param list2 列表2
     * @param idExtractor ID提取函数
     * @return Map包含三个Key: "onlyIn1", "onlyIn2", "common"
     */
    public static <T, K> Map<String, List<T>> splitListsById(List<T> list1, List<T> list2, Function<T, K> idExtractor) {
        // 1. 提取ID集合,用于快速判断存在性
        Set<K> ids1 = list1.stream().map(idExtractor).collect(Collectors.toSet());
        Set<K> ids2 = list2.stream().map(idExtractor).collect(Collectors.toSet());
 
        // 2. 计算ID层面的差集和交集
        Set<K> onlyIn1Ids = new HashSet<>(ids1);
        onlyIn1Ids.removeAll(ids2); // List1独有的ID
 
        Set<K> onlyIn2Ids = new HashSet<>(ids2);
        onlyIn2Ids.removeAll(ids1); // List2独有的ID
 
        Set<K> commonIds = new HashSet<>(ids1);
        commonIds.retainAll(ids2); // 共有的ID
 
        // 3. 根据ID过滤原始对象列表
        List<T> onlyIn1 = list1.stream()
                .filter(item -> onlyIn1Ids.contains(idExtractor.apply(item)))
                .collect(Collectors.toList());
 
        List<T> onlyIn2 = list2.stream()
                .filter(item -> onlyIn2Ids.contains(idExtractor.apply(item)))
                .collect(Collectors.toList());
 
        // 注意:共有部分通常合并两个列表中的元素,或者只取其中一个。
        // 这里策略是:保留list1和list2中所有ID重合的对象(如果业务要求去重或合并对象属性,需额外处理)
        List<T> common = new ArrayList<>();
        common.addAll(list1.stream()
                .filter(item -> commonIds.contains(idExtractor.apply(item)))
                .collect(Collectors.toList()));
//        common.addAll(list2.stream()
//                .filter(item -> commonIds.contains(idExtractor.apply(item)))
//                .collect(Collectors.toList()));
 
        Map<String, List<T>> result = new HashMap<>();
        result.put("onlyIn1", onlyIn1);
        result.put("onlyIn2", onlyIn2);
        result.put("common", common);
 
        return result;
    }
}