我的代码几乎可以解释我的情况。如果没有那么;我调用此方法并返回“错误”值。不知何故,它要么改变一个arraylist的值,要么将它们设置为相等。我做错了什么?
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;
}
答案 0 :(得分:3)
clone()
只创建浅拷贝,在集合的情况下意味着所包含的对象将不被克隆。如果你想深度克隆,你必须自己实现它。
更容易且可能更好的解决方案是完全避免克隆:不是创建原始集合的副本然后修改内容,而是创建新的空集合,遍历原始集合并构建新的{{1}带有修改值的对象。
然后你甚至可以使Piece
不可变,这本身通常是一个好主意。
答案 1 :(得分:2)
java.util.ArrayList#clone
创建列表的浅副本。它不会复制里面的元素,只复制它们的引用。你想做一个深层复制。
答案 2 :(得分:0)
确实存在问题:
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));
确实