更改对象中的值会更改另一个对象

问题描述 投票:1回答:2

我正在制作游戏树。

我输入的问题是,当我将一个对象复制到一个新对象,然后在新对象中进行更改时,旧对象也会更改它的值。

所以它似乎是一个参考问题。

但是如何使新对象成为一个独立的实例。

在创建从父对象复制的子对象,然后更改子对象中的值之后,父对象也会更改,并且在方法的末尾将打印对象相等。

private void generateSubTree(State parent, int depth) {
    if (depth == 0) {
        System.out.println("End of leaf..!");
        return;
    }
    ArrayList<State> listOfStates = GameEngine.legalMoves(parent);
    for (State s: listOfStates) {
        Board tempBoard = new Board(parent.getBoard().getBoard());
        BoardPiece pieceRef = new BoardPiece();
        State child = new State(parent);
        if(parent.getTurn() == 0) {
            pieceRef = GameEngine.checkForPiece(child.getPlayer1(), s.getMove().getFromX(), s.getMove().getFromY());
            pieceRef.updatePosition(s.getMove().getToX(), s.getMove().getToY());
            tempBoard.updateBoard(child.getPlayer1(), s.getMove(), false);
        } else {
            pieceRef = GameEngine.checkForPiece(child.getPlayer2(),  s.getMove().getFromX(),  s.getMove().getFromY());
            pieceRef.updatePosition(s.getMove().getToX(), s.getMove().getToY());
            tempBoard.updateBoard(child.getPlayer2(), s.getMove(), false);  
            }
        child.setBoard(tempBoard);
        parent.addChild(child);
        System.out.println("Is parent equal to child: " + child.equals(parent));
        i++;
        System.out.println("States generated: " + i);
        generateSubTree(child,depth-1);
    }

}

public class State{

private Board board;
private int turn;
private Move move;
private ArrayList<Move> legalMoves;
private int depth;
private int utilityVal;
private Player player1;
private Player player2;

private State parent;
private ArrayList<State> children;

public State() {
    children = new ArrayList<>();
}

// Copy constructor
public State(State state) {
    this.parent = state.parent;
    this.depth = state.depth;
    this.board = state.board;
    this.children = state.children;
    this.turn = 1 - state.turn;
    this.player1 = state.player1;
    this.player2 = state.player2;
    // shallow copy
    // this.subjects = student.subjects;

    // deep copy - create new instance of HashSet
//  this.subjects = new HashSet<>(state.subjects);
}

预期的结果是我可以在不更改Parent的情况下更改对象Child

java
2个回答
0
投票
    // Copy constructor
public State(State state) {
    this.parent = state.parent;
    this.depth = state.depth;
    this.board = state.board;
    this.children = state.children;
    this.turn = 1 - state.turn;
    this.player1 = state.player1;
    this.player2 = state.player2;
    // shallow copy
    // this.subjects = student.subjects;

    // deep copy - create new instance of HashSet
//  this.subjects = new HashSet<>(state.subjects);
}

您的复制构造函数不会复制。您提供对另一个对象的引用,它们指向相同的父对象,深度,板,子等。您应该为每个对象创建另一个复制构造函数,直到原始类型。例如,如果董事会包含两个整数:

class Board {
int a;
int b;

public Board(Board board){
   this.a = board.a;
   this.b = board.b;
}

并使用此构造函数:

this.board = new Board(state.board);

代替:

this.board = state.board;

1
投票

但是如何使新对象成为一个独立的实例。

删除static关键字以使对象内的字段独立于其他对象。

如果字段/变量是static,则它与该类的所有实例共享其值。如果更改其中一个,则更改所有实例的值。

我认为主要的问题是你复制State对象。您没有真正复制任何只将引用传递给另一个实例的内容。

你需要一个deepCopy方法,它也复制自己必须复制自己的所有字段的实例。

必须在作为新对象一部分的所有字段中进行深度复制。在这里你必须复制BoardPlayerMove等。对于原始数据类型,您的副本可以按原样工作。

© www.soinside.com 2019 - 2024. All rights reserved.