当更改克隆数组的值时,更改源数组的值

When change values of cloned array, changes the source array values

请看下面的代码,我有两个二维数组,当我更改 goalState 数组的值时,startState 的值会更改:

public static void main(String[] args) throws CloneNotSupportedException {
    int[][] startState = new int[][]{{1, 2, 3}, {8, 0, 4}, {7, 6, 5}};
    int[][] goalState = new int[][]{};

    goalState = startState.clone();

    goalState[0][1] = 12;

    System.out.println(Arrays.deepToString(startState));
    System.out.println(Arrays.deepToString(goalState));
}

输出:

[[1, 12, 3], [8, 0, 4], [7, 6, 5]]
[[1, 12, 3], [8, 0, 4], [7, 6, 5]]

您需要如下克隆,

for (int i=0; i<startState.length; i++) {
    goalState[i] = startState[i].clone();
}

有java-8+,

int[][] goalState = Arrays.stream(startState)
                          .map(int[]::clone)
                          .toArray(int[][]::new);

因此,在分析了代码的堆转储之后,似乎在执行 startState.clone(),然后从startState 到 goalState

GoalState 内存对象: 这就是为什么您在 goalState 中所做的任何更改都会反映在 startState 中,反之亦然。

所以,为了解决这个问题,您需要做的是:

    int[][] startState = new int[][]{{1, 2, 3}, {8, 0, 4}, {7, 6, 5}};
    int[][] goalState = new int[startState.length][startState[0].length];

    for(int i=0;i<startState.length;i++)
    {goalState[i]=startState[i].clone();}

注意,这仅适用于原始类型数组,因为在原始类型 1d 数组中,仅复制 int 值,这就是我们也可以在克隆 2d 数组时使用此功能的原因