为什么我的二维阵列克隆不止一次?
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)如果它们的长度不匹配,但是您可能会确保它们这样做。
我想将 '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)如果它们的长度不匹配,但是您可能会确保它们这样做。