【问题标题】:When change values of cloned array, changes the source array values更改克隆数组的值时,更改源数组值
【发布时间】:2020-08-31 06:20:48
【问题描述】:

请看下面的代码,我有两个二维数组,当我改变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]]

【问题讨论】:

标签: java arrays clone


【解决方案1】:

所以,在分析了代码的堆转储之后,似乎在执行 startState.clone(),然后一维数组的所有引用(如 {1,2,3} 的引用)都从 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 数组

【讨论】:

    【解决方案2】:

    你需要克隆如下,

    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);
    

    【讨论】:

    • 为什么会这样:clone() 本质上是一个浅拷贝 (stackoverflow.com/questions/1175620/…),因此如果您不想同时更改两个对象,则需要“深入”并分别克隆每个对象跨度>
    猜你喜欢
    • 1970-01-01
    • 2020-12-25
    • 2018-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多