【问题标题】:Java; two local clones of one arraylist are making their values equal?爪哇;一个数组列表的两个本地克隆使它们的值相等?
【发布时间】:2012-02-25 20:28:13
【问题描述】:

我的代码应该可以很好地解释我的情况。如果没有,那么;我调用此方法并返回“错误”值。不知何故,它要么改变了一个数组列表的值,要么将它们设置为相等。我做错了什么?

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

【问题讨论】:

  • 哪行代码没有达到你的预期?您的期望是什么?行为有何不同?

标签: java arraylist


【解决方案1】:

clone() 只创建浅拷贝,这在集合的情况下意味着包含的对象将不会被克隆。如果你想要深度克隆,你必须自己实现。

一个更简单且可能更好的解决方案是完全避免克隆:与其创建原始集合的副本然后修改内容,您可以创建一个新的空集合,遍历原始集合并构建一个新的 Piece 对象使用修改后的值。

然后您甚至可以使Piece 不可变,这本身通常是一个好主意。

【讨论】:

    【解决方案2】:

    java.util.ArrayList#clone 创建列表的 副本。它不复制里面的元素,只复制对它们的引用。你想做一个深拷贝。

    【讨论】:

      【解决方案3】:

      问题确实存在:

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

      clone 方法不对列表执行深度克隆。所以两个列表共享相同的对象。当你这样做时

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

      你覆盖了什么

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

      做了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-07-23
        • 1970-01-01
        • 1970-01-01
        • 2012-01-14
        • 2020-06-06
        • 1970-01-01
        相关资源
        最近更新 更多