为何HashMap的entrySet在if条件外显示异常?代码问题排查
代码问题分析与解决
问题根源
- 引用传递特性导致数据同步变更:你往HashMap里存的是
recordList这个ArrayList对象的内存引用,不是独立的集合副本。当执行recordList.clear()时,修改的是该引用指向的同一个集合实例,所以HashMap中对应的value会同步变成空集合——if内打印时集合还没被清空,外部打印时已经执行了clear操作,自然输出不一致。 - 批量逻辑判断不合理:当前if条件
recordList.size() > 0会在每次循环触发(刚add完元素,size肯定大于0),导致每循环一次就存一次集合再清空,这和你“批量存入1000条”的初衷不符,但这不是输出不一致的直接原因。
解决方法
- 存入集合副本而非原引用:每次向HashMap存集合时,创建新的ArrayList对象并复制原集合元素,避免后续修改影响已存入的数据。把
recordbatchof1000.put(c, recordList);修改为:
recordbatchof1000.put(c, new ArrayList<>(recordList));
- 修正批量判断逻辑:把if条件改成按预期的批量大小判断,比如要每1000条存一次,就写成
if (recordList.size() == 1000),同时循环结束后要处理最后一批不足1000条的剩余数据。
修改后的示例代码
public class test{ public static void main(String args[]) { ArrayList <String>recordList = new ArrayList(); int c = 1; HashMap<Integer, ArrayList<String>> recordbatchof1000 = new HashMap<>(); // 定义批量大小,可根据需求改为1000 int batchSize = 10; for (int i = 0; i < 10; i++) { recordList.add(String.valueOf(i)); if (recordList.size() == batchSize) { // 存入新的集合副本 recordbatchof1000.put(c, new ArrayList<>(recordList)); System.out.println("DEBUG:: The value of the map is inside if condition::" + recordbatchof1000.entrySet()); c++; recordList.clear(); } System.out.println("DEBUG:: The value of the map is outside if condition::" + recordbatchof1000.entrySet()); } // 处理最后一批不足批量大小的数据 if (!recordList.isEmpty()) { recordbatchof1000.put(c, new ArrayList<>(recordList)); } } }
修改后,HashMap中存储的都是独立的集合实例,原集合clear后不会影响已存入的数据,if条件内外的输出会保持一致,同时也实现了批量存储的逻辑。
内容的提问来源于stack exchange,提问作者Shaheaz
相关产品推荐
相关产品推荐

