2014-12-31 23 views
6

Mam problem z wykonaniem kopii obiektu do użycia i zmian wartości dla tej kopii, zamiast tego zmienia wartości dla obu moich obiektów. Kod obiektu.Nie można skopiować obiektu i zmienić wartości

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

i kod dla funkcji, które Próbowałem dostać się do pracy

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

Więc gdy próbuję wstawić wartość 1 w nowym obiekcie stary ciągle zmienia.

+0

czy to się kompiluje? lub dostaniesz jakieś inne komunikaty o błędach? – ochi

Odpowiedz

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

to make deska i punkt układ w tym samym adresem. Spróbuj czegoś takiego:

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]; 
} 
+0

@Dom mój błąd, dzięki za wskazanie go! – issathink

2

Po przypisaniu zmiennej tablicowej do istniejącej tablicy, nie otrzymasz nowej tablicy. Otrzymujesz dwa odniesienia do tej samej tablicy.

na przykład:

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

a i b nie są dwie tablice, lecz dwa odnośniki w takim samym układzie. Następnie zmiana a jest taka sama jak zmiana b.

W przypadku macierzy 2D występuje inny haczyk: tablica int[][] x jest w rzeczywistości tablicą zawierającą sekwencję innych tablic. Tak więc naiwna kopia tego (int[][] y = x.clone()) dałaby dwie tablice int[][] zawierające wspólne odniesienia do sekwencji macierzy int[].

Poprawne skopiowanie tablicy 2D wymaga skopiowania pojedynczych tablic 1D znajdujących się wewnątrz niej.

-

W twoim przypadku, obie twoje obiekty posiadają odniesień do tej samej tablicy. Jeśli chcesz, aby miały oddzielne tablice, musisz skopiować tablicę. Można skopiować tablicę w konstruktorze tak:

public Board(int[][] layout) { 
    board = new int[layout.length][]; 
    for (int i = 0; i < layout.length; ++i) { 
     board[i] = layout[i].clone(); 
    } 
} 
+0

Nie zadałem tego pytania, ale dla moich celów edukacyjnych możesz wyjaśnić to: "Oba twoje obiekty zawierają odniesienia do tej samej tablicy". dla mnie, jeśli nie masz nic przeciwko? –

+0

@KickButtowski 'int [] []' jest typem obiektu. OP użył odwołania do obiektu 'board' instancji" A "i przekazał je instancji" B ". Ale ponieważ konstruktor bezpośrednio przypisuje dostarczoną tablicę 2d do zmiennej instancji 'board'. Oznacza to, że nie utworzył kopii, tak jak myślał, po prostu * udostępnił * to odwołanie, więc obie instancje go używają. – Tom

+0

dziękuję, ale czy ktoś może rozszyfrować kod, bo go nie widzę. Całkowicie dostaję to, co widzisz, ale nie mogę nawiązać połączenia między tym, co mówiliście, a fragmentem kodu: –

1

trzeba skopiować tablicę layout również.

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