【BUG】循环中重复使用对象一定要注意

有时候博客内容会有变动,首发博客是最新的,其他博客地址可能未同步,请认准https://blog.zysicyj.top

首发博客地址

文章更新计划

系列文章地址


报错内容

报错信息显示ID重复。

原因分析

在最终添加的方法中,出现了重复ID的报错。对于为什么ID会重复,我思考了很久也没有想通。我沿着代码往上找到了saveList

java 复制代码
int batchSize = 5000;
if (CollUtil.isNotEmpty(saveList)) {
    List<List<Map<String, Object>>> batchList = ListUtil.partition(saveList, batchSize);
    for (List<Map<String, Object>> batch : batchList) {
        if (CollUtil.isNotEmpty(batch)) {
            firstRecordMapper.insertJghzLdryList(batch.stream().filter(v -> v != null && ObjectUtil.isNotEmpty(v.get("ID"))).collect(Collectors.toList()));
        }
    }
}

代码大致如上所示。

java 复制代码
for (Map<String, Object> item : list) {
    ...
    Map<String, Object> oneCellMap = new HashMap<String, Object>();
    // 遍历这一类型的10个二级指标,每个指标存成一行数据
    for (int i = 0; i < secIndexNameList.size(); i++) {
        ...
        oneCellMap.clear();
        oneCellMap.put("ID", IdUtilV2.getInstance().getId());
        ...
        saveList.add(oneCellMap);
        px++;
    }
    // 保存这一行数据的 综合得分
    oneCellMap.clear();
    oneCellMap.put("ID", IdUtilV2.getInstance().getId());
    ...
    saveList.add(oneCellMap);
}

我也不是很确定,但我怀疑问题出在这里,于是我做了以下修改:

java 复制代码
for (Map<String, Object> item : list) {
    ...
    // 遍历这一类型的10个二级指标,每个指标存成一行数据
    for (int i = 0; i < secIndexNameList.size(); i++) {
        ...
        Map<String, Object> oneCellMap = new HashMap<String, Object>();
        oneCellMap.put("ID", IdUtilV2.getInstance().getId());
        ...
        saveList.add(oneCellMap);
        px++;
    }
    // 保存这一行数据的 综合得分
    Map<String, Object> oneCellMap = new HashMap<String, Object>();
    oneCellMap.put("ID", IdUtilV2.getInstance().getId());
    ...
    saveList.add(oneCellMap);
}

然后问题就解决了。我感到很奇怪,后来才反应过来...原来是使用了同一个对象。

解决方案

问题的根本原因是在循环中重复使用了同一个oneCellMap对象,导致了ID重复的问题。在第一个版本的代码中,每次循环都会清空oneCellMap对象并重新添加ID,但是由于saveList中保存的是引用,所以最终saveList中的所有oneCellMap对象的ID都是相同的。

在修改后的代码中,每次循环都创建了一个新的oneCellMap对象,确保了每个oneCellMap对象的ID都是唯一的,解决了ID重复的问题。

本文由mdnice多平台发布

相关推荐
葫芦和十三1 小时前
图解 MongoDB 05|文档模型设计:内嵌 vs 引用,反范式不是免费午餐
后端·mongodb·agent
不能放弃治疗5 小时前
单 Agent 实现模式
后端
IT_陈寒7 小时前
Redis内存爆了,原来我漏掉了这个致命配置
前端·人工智能·后端
fliter7 小时前
最后一块拼图:用 bitvec 构造 IPv4 包,真正做出自己的 Ping
后端
fliter8 小时前
用 Rust 解析并生成 ICMP 包:checksum、nom 与 cookie-factory
后端
蝎子莱莱爱打怪8 小时前
XZLL-IM干货系列 03|消息 ID 设计:一个 UUID 搞不定的事,我用两个 ID 解决了
后端·面试·开源
fliter8 小时前
从 panic 到 Result:用 Rust 重新整理一个 ping 项目的错误处理
后端
森蓝情丶9 小时前
我给 AI 搭了个法庭:一个前端仔的 LangGraph 实战全记录
前端·后端
JensCS猿9 小时前
从 Spring Boot 回看 SSM 框架:手动挡与自动挡的驾驶哲学
后端
爱勇宝9 小时前
干了近 8 年,一夜之间被裁:AI 时代,程序员最该害怕的不是 AI
前端·后端·程序员