You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

定义的Integer键-ArrayList值HashMap为何覆盖所有先前键的值?

问题原因与解决方案

嘿,这个问题我太熟悉了——你不小心踩了Java中对象引用的坑!

问题根源

你只在方法开头创建了一个ArrayList<String> array2实例,之后每次循环里只是调用array2.clear()清空元素,再添加新内容,然后把这个array2的引用存入HashMap。

但HashMap存储的是对象的引用地址,不是对象本身。这意味着你所有的键(1、2、3...)最终指向的都是同一个ArrayList对象。当最后一次循环结束时,这个对象里的内容就是最后一次迭代添加的元素,所以你看到所有键对应的值都和最后一次的一样。

修复方案

最直接的解决办法是:每次外层循环时都创建一个新的ArrayList实例,而不是复用同一个对象。这样每个键都会关联一个独立的ArrayList,它们的内容不会互相覆盖。

修改后的代码如下:

public void showComplaints(DataSnapshot dataSnapshot) {
    ArrayList<String> array1 = new ArrayList<>();
    String num;
    Log.d("showComplaints", "entered");
    Integer i=1;
    array1.clear();
    
    for (DataSnapshot ds : dataSnapshot.getChildren()) {
        array1.add("Complaint ".toUpperCase() + i);
        // 每次循环都新建一个array2实例,确保每个键对应独立的列表
        ArrayList<String> array2 = new ArrayList<>(); 
        
        for(DataSnapshot innerDS: ds.getChildren()){
            String complaintStuff = innerDS.getValue().toString();
            num = innerDS.getKey().toString();
            array2.add(num + " - " + complaintStuff);
        }
        
        hashMap.put(i, array2);
        array1.add("\n");
        i++;
    }
}

额外说明

如果你出于某种原因非要复用array2变量,也可以在存入HashMap时创建一个副本,比如:

hashMap.put(i, new ArrayList<>(array2));

不过这种方式需要额外复制元素,效率不如直接新建实例高,所以更推荐第一种方案。

内容的提问来源于stack exchange,提问作者Keerthi V

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:32:34