为什么我的2D阵列克隆不止一次?

时间:2019-07-26 16:04:17

标签: java arrays multidimensional-array copy clone

我只想将'线索'数组复制到'木板'数组一次 。复制一次后,线索数组为什么会随板一起变化?

public class Ejewbo
{
    public static int[][] board = new int[9][9];
    public static int[][] clues = 
        {
            {0, 0, 0, 7, 0, 0, 0, 0, 0},
            {1, 0, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 4, 3, 0, 2, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 0, 6},
            {0, 0, 0, 5, 0, 9, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 4, 1, 8},
            {0, 0, 0, 0, 8, 1, 0, 0, 0},
            {0, 0, 2, 0, 0, 0, 0, 5, 0},
            {0, 4, 0, 0, 0, 0, 3, 0, 0},
        };

    public static void main(String[] args)
    {
        Ejewbo.board = Ejewbo.clues.clone();
        test();
    }

    public static void printboth()
    {
        for (int j = 0; j < 9; j++)
        {
            for (int i = 0; i < 9; i++)
            {
                System.out.print(Ejewbo.board[j][i]);
                System.out.print(" ");
            }

            System.out.println();
        }

        System.out.println();

        for (int j = 0; j < 9; j++)
        {
            for (int i = 0; i < 9; i++)
            {
                System.out.print(Ejewbo.clues[j][i]);
                System.out.print(" ");
            }

            System.out.println();
        }

        System.out.println("-----");
    }

    public static void test()
    {
        for (int i = 0; i < 2; i++) //run twice to see issue
        {
            Ejewbo.board[0][0]++;
            printboth();
        }
    }
}

我希望线索数组不会改变,但是确实会改变。董事会变更后,线索也随之改变。为什么?有没有更好的方法来复制像这样的数组(而不是使用.clone())?

编辑:第一个答案here似乎是我复制数组的好方法。

3 个答案:

答案 0 :(得分:0)

快速提示

为此,您可以将9替换为board.length,以防万一您更改电路板尺寸时必须更改其他所有内容。

for (int j = 0; j < 9; j++)
        {
            for (int i = 0; i < 9; i++)

所以它只调用一次的原因是这部分代码 您需要能够在调用板阵列并用++更新时调用线索阵列;

for (int i = 0; i < 2; i++) //run twice to see issue
            {
                Ejewbo.board[0][0]++;
                printboth();
            }
        }

答案 1 :(得分:0)

因为clone()正在做浅表复制。

查看以下答案:calling clone on an array

答案 2 :(得分:0)

(以下代码块未经测试)

致电时:

Ejewbo.board = Ejewbo.clues.clone();    

您正在创建浅表副本。结果是您观察到的行为,board [i] [j] =线索[i] [j]。他们指向的是内存中相同的引用,因此对一个引用的任何更改也将对另一个引用进行更改。

您可以做的是使用类似的方法在2D数组本身上进行迭代

for(int i=0; i<clues.length; i++) {
 for(int j=0; j<clues[i].length; j++) {
  board[i][j]=clues[i][j];
 }
}

请注意,Arrays类具有一种用于复制一维数组内容的方法,称为copyOf。因此上述代码可以简化为

for(int i=0; i<clues.length; i++) {
 board[i]=Arrays.copyOf(clues[i], board[i].length);
}

请注意,如果Arrays.copyOf方法的长度不匹配,则会截断多余的元素或pad元素(即为int数组添加0),但是您可能会确保这样做。