Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't copy my object and change values

Tags:

java

object

I'm having problems making a copy of an object to use and change values for that copy, instead it changes the values for both of my objects. Code for the object.

public class Board {
    private int[][] board;

    public Board() {
        board = new int[9][9];
    }
    public Board(int[][] layout){
        board = layout;
    }

    public int[][] getBoard(){
        return board;
    }
    public int getBoardValue(int y, int x){
        return board[y][x];
    }
    public void insertValue(int v, int y, int x){
        board[y][x] =v;
    }
}

And code for the function that I've been trying to get to work

public Board copy(Board b) {
    Node node = new Node(b);
    int[][] layout = node.getBoard().getBoard();
    Board temp = new Board(layout);
    temp.insertValue(1,4,5);
    return temp;
}

So when I try to insert the value 1 in the new object the old one still changes.

like image 973
rulred Avatar asked Dec 31 '14 01:12

rulred


People also ask

Can an object be copied?

There are several ways to copy an object, most commonly by a copy constructor or cloning. Copying is done mostly so the copy can be modified or moved, or the current value preserved. If either of these is unneeded, a reference to the original data is sufficient and more efficient, as no copying occurs.

How do you copy an object to another?

The Object. assign() method can be used to merge two objects and copy the result to a new target. Just like the spread operator, If the source objects have the same property name, the latter object will replace the preceding object. Now, let's look at another example of merging in Typescript.


3 Answers

public Board(int[][] layout){
  board = layout;
}

This make board and layout point at the same adress. Try something like :

public Board(int[][] layout){
  this();
  for(int i=0; i<layout.length;i++)
   for(int j=0; j<layout[0].length;j++)
      board[i][j] = layout[i][j];
}
like image 83
issathink Avatar answered Sep 26 '22 00:09

issathink


When you assign an array variable to an existing array, you don't get a new array. You get two references to the same array.

For instance:

int[] a = { 1, 2, 3};
int[] b = a;

a and b are not two arrays, but two references to the same array. Subsequently altering a is the same as altering b.

With 2D arrays there is another catch: an array int[][] x is actually an array holding a sequence of other arrays. So a naive copy of it (int[][] y = x.clone()) would give you two int[][] arrays holding shared references to a sequence of int[] arrays.

To properly copy a 2D array requires copying the individual 1D arrays inside it.

--

In your case, both your objects hold references to the same array. If you want them to have separate arrays you need to copy the array. You could copy the array in the constructor like this:

public Board(int[][] layout) {
    board = new int[layout.length][];
    for (int i = 0; i < layout.length; ++i) {
        board[i] = layout[i].clone();
    }
}
like image 21
khelwood Avatar answered Sep 23 '22 00:09

khelwood


You have to copy the layout array as well.

public Board copy(Board b) {
    Node node = new Node(b);
    int[][] oldLayout = node.getBoard().getBoard();
    int[][] newLayout = new int[9][9];
    for(int i=0; i<newLayout.length; i++) {
        newLayout[i] = Arrays.copyOf(oldLayout[i], oldLayout[i].length);
    }
    Board temp = new Board(newLayout);
    temp.insertValue(1,4,5);
    return temp;
}
like image 25
Greg Avatar answered Sep 26 '22 00:09

Greg