我很困惑。
这是我对基本变量和赋值的理解:
int a = 9;
int b = a;
int a = 8;
System.out.println(b); // This will be 9
现在我正在尝试同样的事情,但我使用的是ArrayList二维结构而不是基本类型,请参阅以下代码:
public final class Matrix {
private List<List<Double>> rawMatrix = new ArrayList<List<Double>>();
private List<List<Double>> matrix = new ArrayList<List<Double>>();
private void update(){
matrix = rawMatrix;
System.out.println("matrix: "+matrix.size()+", "+matrix.get(0).size());
System.out.println("matrix: "+rawMatrix.size()+", "+rawMatrix.get(0).size());
matrix.get(0).add(99.0);
System.out.println("matrix: "+matrix.size()+", "+matrix.get(0).size());
System.out.println("matrix: "+rawMatrix.size()+", "+rawMatrix.get(0).size());
}
}
问题在于输出:
matrix: 4, 3
matrix: 4, 3
matrix: 4, 4
matrix: 4, 4
现在由于某种原因,rawMatrix
添加了与matrix
相同的元素,即使我从未在rawMatrix
结构中添加任何内容。
我认为这是一种通过引用分配变量的奇怪类型,我不太明白为什么会这样,以及为什么它是Java中的默认值。
我如何克服这个问题?我是否必须使用两个for循环才能让我的一个矩阵与另一个矩阵相等,这似乎非常低效。
答案 0 :(得分:2)
由于ArrayLists是对象,因此赋值只是将指针复制到对象。 对于原始类型,您实际上是在复制值。
这意味着您的分配matrix = rawMatrix;
会使matrix
指向与rawMatrix
相同的内存位置,当更新内存时,更改也会反映到matrix
的位置分。
答案 1 :(得分:1)
这一行:
matrix = rawMatrix;
使matrix
引用rawMatrix
。之后,您只能引用一个ArrayList<List<Double>>
对象,并且两个变量都设置为此引用。 (我怀疑其他ArrayList
将无法访问并获得gc-ed,如果您不在其他地方使用它的话)
答案 2 :(得分:1)
更新方法中的第一个语句是
matrix = rawMatrix;
因此,你的引用变量矩阵和rawMatrix都引用了List&gt;的相同问题。
因此,尽管您使用此变量中的任何一个添加元素,但两者都会产生相同的答案,因为它们都引用同一个对象。
答案 3 :(得分:0)
因为矩阵是rawMatrix
您创建了两个对象
private List<List<Double>> rawMatrix = new ArrayList<List<Double>>();
private List<List<Double>> matrix = new ArrayList<List<Double>>();
然后你改变了你创建的矩阵(新对象),由rawMatrix分配,以便rawMatrix更改了对象矩阵并产生了结果。
matrix = rawMatrix;
答案 4 :(得分:0)
int是原始数据类型。这意味着当您为其分配时,您可以为其指定实际值。
通过引用分配对象。这意味着matrix = rawMatrix
行将设置矩阵所引用的对象与rawMatrix引用的对象相同。
如果需要重复对象,则必须使用适当的克隆或复制方法或创建新对象并自行填充。请记住(在适当的时候)您可能希望保持“深度”复制数组本身中的对象。使用这样的嵌套数组,您可能希望复制“内部”列表。