• JAVA在循环中重复使用同一个对象导致的ID重复问题
  • 发布于 2个月前
  • 202 热度
    0 评论
报错内容
报错信息显示 ID 重复。

原因分析
在最终添加的方法中,出现了重复 ID 的报错。对于为什么 ID 会重复,我思考了很久也没有想通。我沿着代码往上找到了 saveList。
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()));
        }
    }
}
代码大致如上所示。
for (Map<String, Object> item : list) {
    ...
    Map<String, Object> oneCellMap = new HashMap<String, Object>();
    // 遍历这一类型的10个二级指标,每个指标存成一行数据
    for (int i = 0; i < secIndexNameList.size(); i++) {
        // 堆代码 duidaima.com
        oneCellMap.clear();
        oneCellMap.put("ID", IdUtilV2.getInstance().getId());
        ...
        saveList.add(oneCellMap);
        px++;
    }
    // 保存这一行数据的 综合得分
    oneCellMap.clear();
    oneCellMap.put("ID", IdUtilV2.getInstance().getId());
    ...
    saveList.add(oneCellMap);
}
我也不是很确定,但我怀疑问题出在这里,于是我做了以下修改:
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 重复的问题。
用户评论