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());
    }
相关推荐
zed_233 分钟前
Agent 是什么:从「问答」到「会用工具」
后端
m0_587383005 分钟前
无人自助拼豆系统核心功能开发与部署落地全流程实战指南
java·经验分享·后端·struts·架构
毕业设计70310 分钟前
(免费领源码)基于node的学生公寓管理系统06412- java、PHP、python、C#、小程序、大数据、单片机、网络工程等)
vue.js·mysql·node.js·maven·mybatis·express·b/s
phil613 分钟前
打进沙箱的电话都走哪儿?看懂Sandbox的网络设计
后端
雷一言说14 分钟前
Spring AI 2.0:RAG 文档分块大小策略选择
java·spring
XIAEE15 分钟前
Java 世界历险记:从一行 System.out.println 到整个 Spring 宇宙
java·spring
XIAEE17 分钟前
微前端狂想曲:我试图让三个不同门派的前端住进同一栋楼
java·spring
iOS开发上架哦17 分钟前
抓包怎么修改响应?响应头、响应体、脚本注入实操教程
后端·ios
XIAEE17 分钟前
Linux 生存指南:从"终端恐惧症"到"命令行老司机"
java·spring
XIAEE18 分钟前
实战教程:手机端死活调不出摄像头?聊聊安全上下文(Secure Context)
java·spring