JAVA 对比老、新两个列表,找出新增、修改、删除的数据

  • 工具类
java 复制代码
 /**
     * 对比老、新两个列表,找出新增、修改、删除的数据
     *
     * @param oldList  老列表
     * @param newList  新列表
     * @param sameFunc 对比函数,返回 true 表示相同,返回 false 表示不同
     *                 注意,same 是通过每个元素的"标识",判断它们是不是同一个数据
     * @return [新增列表、修改列表、删除列表]
     */
    public static <T> List<List<T>> diffList(Collection<T> oldList, Collection<T> newList,
                                             BiFunction<T, T, Boolean> sameFunc) {
        List<T> createList = new LinkedList<>(newList); // 默认都认为是新增的,后续会进行移除
        List<T> updateList = new ArrayList<>();
        List<T> deleteList = new ArrayList<>();

        // 通过以 oldList 为主遍历,找出 updateList 和 deleteList
        for (T oldObj : oldList) {
            // 1. 寻找是否有匹配的
            T foundObj = null;
            for (Iterator<T> iterator = createList.iterator(); iterator.hasNext(); ) {
                T newObj = iterator.next();
                // 1.1 不匹配,则直接跳过
                if (!sameFunc.apply(oldObj, newObj)) {
                    continue;
                }
                // 1.2 匹配,则移除,并结束寻找
                iterator.remove();
                foundObj = newObj;
                break;
            }
            // 2. 匹配添加到 updateList;不匹配则添加到 deleteList 中
            if (foundObj != null) {
                updateList.add(foundObj);
            } else {
                deleteList.add(oldObj);
            }
        }
        return asList(createList, updateList, deleteList);
    }
  • 使用案例
java 复制代码
  private void updateBusinessProduct(Long id, List<ProductDO> newList) {
        List<ProductDO> oldList = productMapper.selectListByBusinessId(id);
        List<List<ProductDO>> diffList = diffList(oldList, newList, // id 不同,就认为是不同的记录
                (oldVal, newVal) -> oldVal.getId().equals(newVal.getId()));
        if (CollUtil.isNotEmpty(diffList.get(0))) {
            diffList.get(0).forEach(o -> o.setBusinessId(id));
            productMapper.insertBatch(diffList.get(0));
        }
        if (CollUtil.isNotEmpty(diffList.get(1))) {
            productMapper.updateBatch(diffList.get(1));
        }
        if (CollUtil.isNotEmpty(diffList.get(2))) {
            productMapper.deleteByIds(convertSet(diffList.get(2), ProductDO::getId));
        }
    }
java 复制代码
  public static <T, U> Set<U> convertSet(Collection<T> from, Function<T, U> func) {
        if (CollUtil.isEmpty(from)) {
            return new HashSet<>();
        }
        return from.stream().map(func).filter(Objects::nonNull).collect(Collectors.toSet());
    }
相关推荐
身如柳絮随风扬3 分钟前
多数据源切换实战:从业务场景到3种实现方案全解析
java·分布式·微服务
skywalk81634 分钟前
在考虑双轨制,即在中文语法的基础上,加上数学公式的支持,这样像很多计算将更加简单方便,就像现在的小学数学课本里面一样,比如:定x=2*x + 1
开发语言
小书房8 分钟前
Kotlin的by
android·开发语言·kotlin·委托·by
就叫飞六吧24 分钟前
QT写一个桌面程序exe并动态打包基本流程(c++)
开发语言·c++
threelab33 分钟前
Three.js 代码云效果 | 三维可视化 / AI 提示词
开发语言·javascript·人工智能
Java小生不才34 分钟前
Spring AI文生音
java·人工智能·spring
凯尔萨厮37 分钟前
Springboot2.x+Thymeleaf项目创建
java
V搜xhliang024642 分钟前
OpenClaw科研全场景用法:从文献到实验室的完整自动化方案
运维·开发语言·人工智能·python·算法·microsoft·自动化
kaikaile19951 小时前
风、浪、流环境模型的船舶三自由度(纵荡、横荡、艏摇)运动仿真MATLAB
开发语言·人工智能·matlab
fish_xk1 小时前
map和set
java·开发语言