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());
    }
相关推荐
羽翼.玫瑰16 小时前
关于重装Python失败(本质是未彻底卸载Python)的问题解决方案综述
开发语言·python
cdut_suye16 小时前
解锁函数的魔力:Python 中的多值传递、灵活参数与无名之美
java·数据库·c++·人工智能·python·机器学习·热榜
CRMEB系统商城16 小时前
CRMEB多商户系统(PHP)- 移动端二开之基本容器组件使用
运维·开发语言·小程序·php
淮北49416 小时前
科研绘图工具R语言
开发语言·r语言
逍遥德16 小时前
java Map Set List 扩容机制
java·开发语言·list
高山上有一只小老虎17 小时前
mybatisplus实现分页查询
java·spring boot·mybatis
2501_9445215917 小时前
Flutter for OpenHarmony 微动漫App实战:图片加载实现
android·开发语言·前端·javascript·flutter·php
nbsaas-boot17 小时前
基于 Java 21 ScopedValue 的多租户动态数据源完整实践
java·开发语言
2301_7806698617 小时前
线程安全、线程同步(三种加锁方式)、线程池(两种创建线程池方式、线程池处理Runnable任务、线程池处理Callable任务)、并发/并行
java
liuc031717 小时前
Java项目关于不同key的读取
java·开发语言