往HashMap对象hm放两组值:key=0 : 0,0和key=1 : 1,2
看一段代码:
HashMap<Integer, int[]> hm = new HashMap<>();
int[] idAndCount = new int[2];
for (int i = 0; i < 2; i++) {
idAndCount[0] = i;
idAndCount[1] = 2*i;
hm.put(key, idAndCount);
}
for (int i = 0; i < 2; i++) { // 显示结果
System.out.println("id" + "i" + ":" + hm.get(i)[0]);
System.out.println("比中数" + "i" + ":" + hm.get(i)[1]);
}
我们想要的输出结果是:
id0:0
比中数0:0
id1:1
比中数1:2
而实际输出结果是,两次循环输出的结果一致,均为1,2:
id0:1
比中数0:2
id1:1
比中数1:2
反复测试后发现问题出在下面这段代码上:
for (int i = 0; i < 2; i++) {
idAndCount[0] = i;
idAndCount[1] = 2*i;
hm.put(key, idAndCount);
}
两次循环往HashMap:hm中输送值的变量均是idAndCount,这是一个引用,其值由最后一次赋值决定,也就是hm中的两行信息的值是一样的。
本以为放进HashMap中就“凝固”了,没想到放进“老窝”里也不安全,主要因为放进去的不是“实值”,而是引用,这一点很迷惑人。
代码做如下修改,就正常了:
HashMap<Integer, int[]> hm = new HashMap<>();
int[][] idAndCount = new int[2][2];
for (int i = 0; i < 2; i++) {
idAndCount[i][0] = i;
idAndCount[i][1] = 2*i;
hm.put(key, idAndCount[i]);
}
for (int i = 0; i < 2; i++) {
System.out.println("id" + "i" + ":" + hm.get(i)[0]);
System.out.println("比中数" + "i" + ":" + hm.get(i)[1]);
}
将一维数组(int[] idAndCount)改为二维数组(int[][] idAndCount),这样为HashMap每行传数的变量就不一样了:
for (int i = 0; i < 2; i++) {
idAndCount[i][0] = i;
idAndCount[i][1] = 2*i;
hm.put(key, idAndCount[i]);
}
也可以每次使用前重新new一次变量,如:
HashMap<Integer, int[]> hm = new HashMap<>();
for (int i = 0; i < 2; i++) {
int[] idAndCount = new int[2];
idAndCount[0] = i;
idAndCount[1] = 2*i;
hm.put(key, idAndCount);
}
for (int i = 0; i < 2; i++) { // 显示结果
System.out.println("id" + "i" + ":" + hm.get(i)[0]);
System.out.println("比中数" + "i" + ":" + hm.get(i)[1]);
}
将int[] idAndCount = new int[2];从循环外搬到循环内即可。
结论:往HashMap每行输送(put()方法)值的变量名(准确地说是引用的地址)不可以相同。