如何在java中克隆多维数组?
编辑2:下面是一段基于DuffyMo响应的代码片段,说明了如何使用System.arraycopy绕过多维数组克隆的限制如何在java中克隆多维数组?,java,arrays,cloning,Java,Arrays,Cloning,编辑2:下面是一段基于DuffyMo响应的代码片段,说明了如何使用System.arraycopy绕过多维数组克隆的限制 import java.util.Arrays; public class Randar { public static int[][] arrayMaster = {{6,1}, {10,1}, {1,1}}; private static int[][] arrayChanges = new int[arrayMaster.length][2]; public Ran
import java.util.Arrays;
public class Randar {
public static int[][] arrayMaster = {{6,1}, {10,1}, {1,1}};
private static int[][] arrayChanges = new int[arrayMaster.length][2];
public Randar () {
}
public static void main(String[] args) {
arrayChanges[0][0] = 0;
resetArrays(arrayChanges, arrayMaster);
arrayChanges[0][0] = 0;
System.out.format("arrayMaster: %s, arrayChanges: %s", Arrays.deepToString(arrayMaster), Arrays.deepToString(arrayChanges));
}
public static void resetArrays(int[][] arrayChanges, int[][] arrayMaster) {
for (int a=0; a< arrayMaster.length; a++) {
System.arraycopy(arrayMaster[a], 0, arrayChanges[a], 0, arrayMaster[a].length);
}
// arrayChanges = arrayMaster.clone(); will NOT work as expected
}
}
当运行上述代码时,arrayMaster会发生更改,arrayChanges也会发生更改,这与我的意图相反。考虑到我可以克隆arrayMaster的每个一维数组成员,我试图解决以下问题:
for (int iter = 0; iter < arrayMaster.length; iter++) {
arrayChanges[iter] = arrayMaster[iter].clone();
}
但是当我运行代码时,由于某种原因,它给出了一个NullPointerException。写一个循环遍历数组各个整数值的方法是我唯一的选择吗
谢谢
编辑1:这也不能解决问题
import java.util.Arrays;
public class Randar {
public int[][] arrayMaster = {{6,1}, {10,1}, {1,1}};
private int[][] arrayChanges = arrayMaster.clone();
public Randar () {
}
public static void main(String[] args) {
Randar Randar1 = new Randar();
Randar1.arrayChanges[0][0] = 0;
resetArrays(Randar1.arrayChanges, Randar1.arrayMaster);
Randar1.arrayChanges[0][0] = 0;
System.out.format("arrayMaster: %s, arrayChanges: %s", Arrays.deepToString(Randar1.arrayMaster), Arrays.deepToString(Randar1.arrayChanges));
}
public static void resetArrays(int[][] arrayChanges, int[][] arrayMaster) {
/*for (int a=0; a< arrayMaster.length; a++) {
System.arraycopy(arrayMaster[a].clone(), 0, arrayChanges[a], 0, arrayMaster[a].length);
} */
arrayChanges = arrayMaster.clone();
}
}
当运行上述代码时,arrayMaster会发生更改,arrayChanges也会发生更改,这与我的意图相反
线路
static private int[][] arrayChanges = arrayMaster;
是罪魁祸首。此行使arrayChanges和arrayMaster指向同一个对象,因此当您从其中一个对象访问该对象时,可以看到对其中一个对象的更改
编辑:克隆多维数组的一个维度时会发生什么
例如,数组在概念上是一个变量列表。如果您只是将另一个变量指定给指向同一数组的la static private int[]arrayChanges=arrayMaster;,您根本没有更改变量集。除了arrayChanges,您没有创建任何新变量,因此您没有从操作系统/JVM获得更多内存,因此您对arrayMaster所做的任何更改都将应用于arrayChanges,反之亦然
现在让我们看一个二维数组。在Java中,二维数组是一组变量,这些变量的属性是每个变量都引用一个一维数组。因此,无论何时克隆二维数组,都会创建一个新的变量列表,每个变量都指向旧变量指向的相同位置。因此,您可以安全地编写arrayChanges[0]=new int[10],而不会影响arrayMaster,但一旦您开始引用arrayChanges[i][j],您仍然会引用arrayMaster引用的第二级数组。要深度复制二维整数数组,您真正需要的是
public static int[][] deepCopyIntMatrix(int[][] input) {
if (input == null)
return null;
int[][] result = new int[input.length][];
for (int r = 0; r < input.length; r++) {
result[r] = input[r].clone();
}
return result;
}
对于那些将来可能会看到这个答案的人来说:是的,最好在这里用T替换int并使该方法通用,但是为了这个目的,更具体的深度复制方法更容易解释清楚。clone进行浅层复制。也就是说,最外面的数组是重复的,但其中存储的值不变。所以如果你有A1={B1,B2,B3}并将其克隆到A2中,A2的初始内容将是{B1,B2,B3}。如果将A1更改为{C1,B2,B3},则A2将保持不变,但如果更改B1的内容而不替换它,则A2将看到该更改
要完成所需的操作,必须循环外部数组并克隆该外部数组的元素(即内部数组)
洋泾浜爪哇语:
int[][] A2 = A1.clone();
for (int i = 0; i < A2.length; i++) {
A2[i] = A2[i].clone();
}
谢谢你的回复。我重写了它,将所有值捆绑到一个类中,不想声明对象的实例,所以这是一个问题。但是,即使使用正确编写的代码,问题仍然存在,正如本文所述,问题根本不是静态的。问题是arrayChanges和arrayMaster这两个名称引用同一个对象。您在声明arrayChanges时创建了一个浅拷贝。有关浅层复制是什么,请参见。@user1184054请将新编写的正确代码发布到问题中。我发布了设置arrayChanges=arrayMaster.clone的代码。那也不行。。。我认为问题在于,克隆多维数组时,数组的一个级别通过值传递,另一个级别通过引用传递。我是个初学者,很明显…答案是错的。for循环:for int r=0;r
int[][] A2 = A1.clone();
for (int i = 0; i < A2.length; i++) {
A2[i] = A2[i].clone();
}