定义的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
相关产品推荐
相关产品推荐

