【问题标题】:Why is my 2D array cloning more than once? [duplicate]为什么我的 2D 阵列克隆不止一次? [复制]
【发布时间】:2019-12-05 00:09:39
【问题描述】:

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

【问题讨论】:

  • 您只是在复制外部数组(浅拷贝)。不过,这两个板仍然指向相同的内部数组。你也需要复制那些(深拷贝)。
  • 使用我的示例进行深层复制的简单方法是什么?我不明白那篇文章中的解决方案。
  • 遍历内部数组并在每个子数组上调用clone 或其他复制方法,然后将副本存储在新的外部数组中。
  • 非常感谢,明白了。

标签: java arrays multidimensional-array copy clone


【解决方案1】:

(以下代码块未经测试)

当你打电话时:

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

您正在创建一个浅拷贝。结果就是您观察到的行为,board[i][j] = 线索[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];
 }
}

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

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

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

【讨论】:

  • 我决定使用这个:``` for (int i = 0; i
【解决方案2】:

还有快速提示

对于下面的这个,您可以用 board.length 替换 9,以防万一您更改了电路板尺寸,您将不得不更改其他所有内容。

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

所以它只调用一次的原因是这部分代码 你需要能够在调用 board 数组并使用 ++ 更新它时调用线索数组;

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

【讨论】:

    【解决方案3】:

    因为 clone() 是在做浅拷贝。

    看看这个答案:calling clone on an array

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-06-12
      • 1970-01-01
      • 1970-01-01
      • 2016-10-10
      • 2013-06-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多