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());
    }
相关推荐
nnerddboy2 分钟前
Rust教程04:引用、借用与切片
开发语言·后端·rust
Rain的Java大神之路12 分钟前
线上接口负载满了如何解决
java·数据库·redis·后端·缓存·面试·架构
jerryinwuhan24 分钟前
《Python数据预处理》第四章
开发语言·python
长江&后浪27 分钟前
防火墙的描述
开发语言·网络·php
counting money30 分钟前
Tomcat 专题:从基础架构到性能调优与 WebSocket 实战
java·websocket·tomcat
观无1 小时前
若依EasyExcel实现单元格合并
开发语言·前端·javascript
雨晨源码(同名B站)1 小时前
基于Python的网易云音乐评论数据情感化分析系统 音乐爬虫信息可视化 |SnowNLP评论情感分析
开发语言·hadoop·爬虫·python·信息可视化·毕业设计
我不是疯子是傻子1 小时前
串口通信数据帧粘包拆包再进化:基于 Qt 的滑动窗口与 CRC 校验实战
开发语言·qt
程序员老陆1 小时前
Qt中实现窗口真全屏(覆盖Windows任务栏)
开发语言·windows·qt
xiaohaiAIgeo1 小时前
【2026年】HG/T 20656-2024化工暖通空调设计规范:新版标准的变化与影响
java·前端·javascript·科普知识