0

I have a 2 dimensional array and stack:

int[][] data = new int[][];
Stack<int[][]> undoList = new Stack<int[][]>(10);

I wanna add the data after every change to keep it in undo list:

undoList.push(data);
// some changes to data array
undoList.push(data);
// some changes to data array
undoList.push(data);

then why do all the stack elements have the same value?

MBH
  • 16,271
  • 19
  • 99
  • 149
  • 1
    Looks like you're using the same reference stored in `data`. Create a new `int[][]` before pushing it into your `Stack`. – Luiggi Mendoza Aug 29 '14 at 16:51
  • 1
    This certainly is a duplicate of a duplicate of a duplicate... But I did not manage to find the start of this chain. – Marco13 Aug 29 '14 at 16:52
  • @Marco13 is data.clone() working here ? – MBH Aug 29 '14 at 16:54
  • 2
    A single `Arrays.copyOf` or `data.clone()` will **NOT** be sufficient. You have to make a deep copy of the array *before* making "some changes". For deep copy examples on 2D arrays, see for example http://stackoverflow.com/a/5563301/3182664 and others – Marco13 Aug 29 '14 at 16:56
  • @Marco13 its a very specific situation that he had a different row sizes in the question you have posted, so ready solution can be more efficient – MBH Aug 29 '14 at 17:01
  • 1
    I'm not sure at which point efficiency should play a role here. You have to create a deep copy of the array. This can be done like in the linked answer (regardless of whether the rows have different lengths or not - for equal-length rows, you would do it in the same way). Alternatively, instead of using `Arrays.copyOf` for each row, one could use `target[i] = input[i].clone();`, but this would also have to be done *for each row*, so there's no significant difference. – Marco13 Aug 29 '14 at 17:05
  • I did a deep copy function, it work so fine. thank you so much @Marco13 – MBH Aug 29 '14 at 17:12

2 Answers2

2

You're making changes to the array - but you're not putting the array itself on the stack... you're putting a reference to the array on the stack. You're basically pushing the same reference several times. If you want independent values, you'll need independent arrays.

Think of a reference as being a bit like a street address written on a piece of paper (where the piece of paper is typically a variable). What you've got at the moment is a book where every page has the same street address on it. You may have gone and painted the front door of the house between writing on every page, but that doesn't mean we can see all those different colours - there's only one house involved. If you want to have the street addresses of lots of different houses with lots of differently-coloured front doors, you need to built lots of different houses...

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
0

I solved it by copying it with this code as @Marco13 has mentioned in the comment above:

Deep Copy

public static int[][] deepCopyArray(int[][] oldArray){
        int[][] newArray = new int[oldArray.length][];
        for(int i=0; i<oldArray.length; i++)
        {
            newArray[i] = new int[oldArray[i].length];
            for(int j=0; j<oldArray[i].length; j++)
                newArray[i][j] = oldArray[i][j];
        }
        return newArray;
    }
MBH
  • 16,271
  • 19
  • 99
  • 149