【问题标题】:Object Assignment Problems对象分配问题
【发布时间】:2016-02-24 10:40:22
【问题描述】:

我在分配对象时遇到问题,该对象会产生一个引用副本,该副本会更改原始对象中的值。

这是我的原始对象

Node root = new Node();
root.filingState("input.txt");

在双端队列数据结构中推送我的根后,我在 tmp 变量

中检索它
Node tmp = deque.pop();

之后,我希望我的 tmp 变量应用所有运算符(上、下、左、右,任何可能的)并检查最佳结果。

            if ( !tmp.goalTest(goal) ) {
                if ( tmp.ifDown() ) {
                    if ( !visited[tmp.getX()+1][tmp.getY()] ) {
                        newDown = new Node(tmp);
                        newDown.moveDown();
                    } else newDown = null;
                } // #EndOfDown!
                if ( tmp.ifUp() ) {
                    if ( !visited[tmp.getX()-1][tmp.getY()] ) {
                        newUp = new Node(tmp);
                        newUp.moveUp();
                    } else newUp = null;
                } // #EndOfUp!
                if ( tmp.ifLeft() ) {
                    if ( !visited[tmp.getX()][tmp.getY()-1] ) {
                        newLeft = new Node(tmp);
                        newLeft.moveLeft();
                    } else newLeft = null;
                } // #EndOfMoveLeft!
                if ( tmp.ifRight() ) {
                    if ( !visited[tmp.getX()][tmp.getY()+1] ) {
                        newRight = new Node(tmp);
                        newRight.moveRight();
                    } else newRight = null;
                } // #EndOfMoveRight!
            } else break;

运算符函数

public boolean ifUp ( ) { return y_blank-1 >= 0; }
public boolean ifDown ( ) { return y_blank+1 <= 4; }
public boolean ifLeft ( ) { return x_blank-1 >= 0; }
public boolean ifRight ( ) { return x_blank+1 <= 4; }

/* Movement functions
    Allows a user to move his blank on board
*/
public void moveUp ( ) {
    board[y_blank][x_blank] = board[y_blank-1][x_blank];
    board[y_blank-1][x_blank] = 'B';

    y_blank -= 1;
} // #EndOfMoveUp!

public void moveLeft ( ) {
    board[y_blank][x_blank] = board[y_blank][x_blank-1];
    board[y_blank][x_blank-1] = 'B';

    x_blank -= 1;
} // #EndOfMoveLeft!

public void moveRight ( ) {
    board[y_blank][x_blank] = board[y_blank][x_blank+1];
    board[y_blank][x_blank+1] = 'B';

    x_blank += 1;
} // #EndOfMoveRight!

public void moveDown ( ) {
    board[y_blank][x_blank] = board[y_blank+1][x_blank];
    board[y_blank+1][x_blank] = 'B';

    y_blank += 1;
} // #EndOfMoveDown!

newDown 第一次迭代失败,因为它不满足条件,我的其他节点通过了条件。

在我的第一个 newUp 应用它的操作符之后,它也改变了 tmp 节点。允许 newLeft、newRight 将运算符应用于新的 tmp 节点值。

Node.java

private char[][] board;

private int x_blank = -1;
private int y_blank = -1;

private Node parent = null;

private Node up = null;
private Node left = null;
private Node right = null;
private Node down = null;

/* Constructor
    Allocates board to a 5x5 2D Array
*/
public Node ( ) { board = new char[5][5]; } 

我尝试创建一个复制构造函数,但没有解决问题。

复制构造函数

public Node ( Node tmp ) {
    this.board = new char[5][5];
    for ( int i=0; i<5; ++i ) {
        for ( int j=0; j<5; ++j ) this.board[i][j] = tmp.board[i][j];
    }

    this.x_blank = tmp.x_blank;
    this.y_blank = tmp.y_blank;

    if ( tmp.parent != null ) this.parent = tmp.parent;

    if ( tmp.up != null ) this.up = tmp.up;
    if ( tmp.left != null ) this.left = tmp.left;
    if ( tmp.right != null ) this.right = tmp.right;
    if ( tmp.down != null ) this.down = tmp.down;
}

所以我的问题是,我如何创建一个可以保存其他对象值的对象,但是当我将运算符应用于新创建的对象时,它不会改变原始对象的值。

【问题讨论】:

    标签: java oop object reference


    【解决方案1】:

    您的复制构造函数不会自动用于将该对象的实例分配给新变量。在 Java 中,对象分配是通过引用来设计的。您需要在分配中明确使用您的复制构造函数:

    Node tmp = new Node(deque.pop());
    

    【讨论】:

    • tmp 似乎很好,因为无论如何它都不会改变,newDown = new Node(tmp);并且新系列的其余部分实际上并没有创建自己的内存域,而是引用 tmps 原始值。
    【解决方案2】:

    我认为最好的方法是实现一个克隆函数,它将创建一个具有相同值的新对象,然后您不会更改原始对象的值。

    例如:

    clone(Node mynode){
        return new Node(mynode.getValue());
        }    
    

    【讨论】:

    • 你应该给出一个更具体的例子来说明如何正确使用/实现克隆。
    • 我真的不明白这部分。你说的克隆是什么意思?我什至没有实现 getValue();
    • clone 是对象类型的方法。来自 javadoc:clone() - 创建并返回此对象的副本。
    猜你喜欢
    • 2012-06-13
    • 2016-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-13
    • 2019-06-08
    相关资源
    最近更新 更多