Джава;два локальных клона одного массива делают свои значения равными? - PullRequest
0 голосов
/ 26 февраля 2012

Мой код должен в значительной степени объяснить мою ситуацию. Если это не так; Я вызываю этот метод, и он возвращает «неправильное» значение. Каким-то образом это либо изменяет значение одного массива, либо устанавливает их равными. Что я делаю не так?

public ArrayList<Piece> bestMove (ArrayList<Piece> b, int index) {

    System.out.println ("possible moves = " +this.getPossibleMoves(b, index)); // prints 2

    if (this.getPossibleMoves(b, index) > 0) { // the problem isn't here

        // is the problem here?
        ArrayList<Piece> cloneAlpha = (ArrayList<Piece>) b.clone();
        ArrayList<Piece> cloneBeta = (ArrayList<Piece>) b.clone();

        int x = b.get(index).x; // x = 4
        int y = b.get(index).y; // y = 3

        // x + 1 = 5
        // y + 1 = 4 
        if (!this.checkSquare(x+1, x+1, cloneAlpha)) {

            cloneAlpha.get(index).setXY((x+1), (x+1));

            System.out.println (cloneAlpha.get(index).x + ", " + cloneAlpha.get(index).y); // prints "5, 4"

        }

        // Something goes on between these two conditions
        // it can't be checkSquare method
        // nor the setXY

        // x - 1 = 3
        // y + 1 = 4
        if (!this.checkSquare(x-1, y+1, cloneBeta)) {

            cloneBeta.get(index).setXY(x-1, y+1);

            System.out.println (cloneBeta.get(index).x + ", " + cloneBeta.get(index).y); // prints "3, 4"

        }


        System.out.println (cloneAlpha.get(index).x + ", " + cloneAlpha.get(index).y); // prints "3, 4"
        System.out.println (cloneBeta.get(index).x + ", " + cloneBeta.get(index).y); // prints "3, 4"

        return cloneAlpha;

    }
    return b;
}

Ответы [ 3 ]

3 голосов
/ 26 февраля 2012

clone() создает только полные копии, что в случае коллекций означает, что содержащиеся в нем объекты не будут клонированы. Если вы хотите глубокое клонирование, вы должны реализовать его самостоятельно.

Гораздо более простым и, вероятно, лучшим решением является полное клонирование: вместо создания копии исходной коллекции, а затем изменения содержимого, вы можете создать новую пустую коллекцию, выполнить итерации по исходной коллекции и создать новый объект Piece. с измененными значениями.

Тогда вы даже можете сделать Piece неизменным, что часто само по себе является хорошей идеей.

2 голосов
/ 26 февраля 2012

java.util.ArrayList#clone создает мелкую копию списка. Он не копирует элементы внутри, только ссылки на них. Вы хотите сделать глубокую копию.

0 голосов
/ 26 февраля 2012

Проблема действительно существует:

ArrayList<Piece> cloneAlpha = (ArrayList<Piece>) b.clone();
ArrayList<Piece> cloneBeta = (ArrayList<Piece>) b.clone();

Метод клонирования не выполняет глубокое клонирование в списке.Таким образом, оба списка используют одни и те же объекты.Когда вы делаете

cloneBeta.get(index).setXY(x-1, y+1);

, вы перезаписываете то, что сделал

cloneAlpha.get(index).setXY((x+1), (x+1));

.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...