为什么我的二维阵列克隆不止一次?

Why is my 2D array cloning more than once?

我想将 'clues' 数组复制到 'board' 数组 仅一次。为什么复制一次后线索数组随棋盘变化?

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 似乎是我复制数组的好方法。

还有快速提示

对于下面的内容,您可以将 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();
            }
        }

因为 clone() 正在进行浅拷贝。

查看此答案:calling clone on an array

(以下代码块未经测试)

当你打电话时:

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

您正在创建一个浅拷贝。结果是您观察到的行为,board[i][j] = clues[i][j]。它们指向内存中的相同引用,因此对一个的任何更改也是对另一个的更改。

你可以做的是用类似

的东西迭代二维数组本身
for(int i=0; i<clues.length; i++) {
 for(int j=0; j<clues[i].length; j++) {
  board[i][j]=clues[i][j];
 }
}

请注意,数组 class 有一种方法可以复制一维数组的内容,称为 copyOf。所以上面的代码可以缩短为

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

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