1

Please see this below code, i have two 2D array, when i change values of the goalState array, the values of startState changes:

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

output:

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

2 Answers2

1

You need to clone as below,

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

With java-8+,

int[][] goalState = Arrays.stream(startState)
                          .map(int[]::clone)
                          .toArray(int[][]::new);
Vikas
  • 6,868
  • 4
  • 27
  • 41
  • Why this works: clone() is essentially a shallow copy (https://stackoverflow.com/questions/1175620/in-java-what-is-a-shallow-copy), so you need to "go deeper" and clone each object separately if you don't want changes to both – Gus May 14 '20 at 17:29
1

So, After analysing heap dump of your code , it seems on doing startState.clone(), then all the references of 1 d array (like reference of {1,2,3}) are copied from startState to goalState

enter image description here

GoalState memory object: enter image description here That's why any change you do in goalState will be reflected in startState and vice -versa.

So , in order to fix this all you need to do is:

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

Note, this will only work in case of primitive type array ,as In primitive type 1d array only value of int is copied, and that's why we can use this feature in cloning of 2d array also

GK7
  • 116
  • 3