在下面的代码中
// Assume there are non-null string arrays arrayA and arrayB
// Code 1
ArrayList<String[]> al = new ArrayList<String[]>();
String[] tmpStr = new String[2];
for (int ii = 0; ii < arrayA.length; ii++) {
tmpStr[0] = arrayA[ii];
tmpStr[1] = arrayB[ii];
al.add(ii, tmpStr);
}
// Code 2
ArrayList<String[]> al = new ArrayList<String[]>();
for (int ii = 0; ii < arrayA.length; ii++) {
String[] tmpStr = new String[2];
tmpStr[0] = arrayA[ii];
tmpStr[1] = arrayB[ii];
al.add(ii, tmpStr);
}
代码2给出了想要的结果 - 也就是说,现在每个索引包含{arrayA(ii),arrayB(ii)}。但是,在代码1中,al包含所有索引的{arrayA(last_index),arrayB(last_index)}。这是为什么?
答案 0 :(得分:5)
Java数组是可变的。您的代码多次添加单个数组,并在每次迭代时修改相同的数组。
答案 1 :(得分:2)
你可能想在这里画一幅画。
在这两种情况下,您都有一个包含多个元素的数组。在第一种情况下,al
中的每个数组元素都指向完全相同的对象。这个共享对象(一个双元素数组)的值不断被写入;在代码片段的末尾,它保存分配给它的最后两个值。在后者中,al
中的每个数组元素都指向一个完全不同的对象。这些对象中的每一个都是通过循环在不同的传递中创建的。
试试吧。绘制这些图表非常有启发性。
答案 2 :(得分:2)
在第一个代码块中,您声明大小为2的字符串数组。因此,它在内存中一次定义,并在循环中将值分配给该引用,因此在每个循环步骤中,其值都会更改,并且'将被添加到ArrayList
对象中。
我是第二个代码块,在循环内部初始化字符串数组,因此每次它将在内存中创建新的数组对象,并且所有对象将具有添加了不同值的不同引用,这将被传递给ArrayList
对象。
这就是为什么你在这里得到不同的价值。
答案 3 :(得分:1)
在case1中,你只会创建String数组。看看在这两种情况下使用new
关键字的次数。在第二种情况下,每次迭代都会在第一种情况下创建几个数组,一次仅在数组上创建。
答案 4 :(得分:1)
tmpStr[]
指向您每次由new String[2];
创建的同一个数组。每当你修改tmpStr[]
内容时,它会覆盖先前的值,因为数组是可变的。
答案 5 :(得分:0)
在代码1中只分配一次内存。并且在相同的内存阵列上,在相同的内存位置初始化了两次。 list包含对该数组的引用。它总是从该数组位置获取数据,因此它将最后给出初始化数组It。所以我们丢失了拳头插入的数据。
但是在代码2中,两个单独的数组在不同的内存位置。所以参考不同。如此正确的答案。