如何在java中克隆多维数组?

如何在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

编辑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 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;rint[][] A2 = A1.clone(); for (int i = 0; i < A2.length; i++) { A2[i] = A2[i].clone(); }