使用while循环向HashMap插入<Key,Value>不生效问题求助
问题原因
- 核心问题是对象引用传递:你在循环外仅初始化了1个
ArrayList对象,所有存入HashMap的键实际都指向同一个ArrayList内存地址。后续调用activities.clear()时会修改所有键关联的列表内容,最终所有值都会同步为最后一次操作的列表数据。 - 次要遗漏问题:循环结束后没有把最后一个ID(示例中的10)对应的列表存入HashMap,所以你的输出结果里没有10这个键。
- 泛型不规范:你声明的
ArrayList activities没有指定泛型,存在类型安全隐患。
修复方案
把activities.clear()替换为新建ArrayList对象即可,同时补充循环结束后的put逻辑,修复后代码如下:
public static void main(String[] args) { int activityRecord = 1; String activitiesFile = "scenarios/BrusselsPopulationFromR/BrusselsActivities.csv"; HashMap<Integer, ArrayList<String>> idAndAllActivities = new HashMap<>(); try { BufferedReader activityReader = new BufferedReader(new FileReader(activitiesFile)); String agentActivity = null; // 初始化带泛型的ArrayList ArrayList<String> activities = new ArrayList<>(); while ((agentActivity = activityReader.readLine()) != null){ String activityWithAllInfo = agentActivity; String[] activitySpilted = agentActivity.split(","); int activityAgentID = Integer.parseInt(activitySpilted[0]); if (activityAgentID == activityRecord){ activities.add(activityWithAllInfo); } else { idAndAllActivities.put(activityRecord, activities); activityRecord = activityAgentID; // 这里不要clear,直接新建新的ArrayList对象 activities = new ArrayList<>(); activities.add(activityWithAllInfo); } } // 补充:循环结束后把最后一个ID对应的列表存入HashMap idAndAllActivities.put(activityRecord, activities); } catch (IOException e) { e.printStackTrace(); } System.out.println(idAndAllActivities); }
额外优化建议(可选)
如果你的CSV文件不一定是按ID升序排列的,可以不用提前判断ID相等,直接用HashMap的API简化逻辑,不需要维护activityRecord变量:
while ((agentActivity = activityReader.readLine()) != null){ String[] activitySpilted = agentActivity.split(","); int activityAgentID = Integer.parseInt(activitySpilted[0]); // 如果ID不存在就新建列表,存在就取出已有列表 ArrayList<String> activities = idAndAllActivities.computeIfAbsent(activityAgentID, k -> new ArrayList<>()); activities.add(agentActivity); }
这种写法不管CSV里的ID顺序是不是乱的都能正常运行,容错性更高。
内容的提问来源于stack exchange,提问作者Jingjun
相关产品推荐
相关产品推荐

