具有矩阵 (Java) 的对象的深拷贝(克隆)
Deep copy (clone) of an object with matrix (Java)
我在深度复制方面遇到了一些问题。
我有这个 java 项目,国际象棋,我需要使用 clone() 方法,因为我需要在不更改棋盘的情况下尝试新的配置。
Board scacchiera = new Board();
Initialization(scacchiera);
Board clone = scacchiera.clone();
System.out.println(scacchiera.toString());
System.out.println(clone.toString());
我创建了一个对象 scacchiera,然后克隆它。我认为我已经正确完成了深拷贝,但是当我在 scacchiera 中更改某些内容时,克隆也会更改。
在对象板中:
public class Board implements Cloneable{
//TODO
//rivedere se check e checkmate public o private;
//se private, costruire get e set;
public Pedine[][] board;
public boolean check;
public boolean checkmate;
//creating 2 lists for all the pieces; Neri=black, Bianchi=White
public ArrayList<Pedine> Neri;
public ArrayList<Pedine> Bianchi;
public Board(){
this.board = new Pedine [8][8];
this.check = false;
this.checkmate = false;
this.Neri = new ArrayList<Pedine>();
this.Bianchi = new ArrayList<Pedine>();
}
...
@Override
public Board clone() throws CloneNotSupportedException{
Board cloned = (Board) super.clone();
cloned.board = (Pedine[][]) board.clone();
return cloned;
}
我有这个双阵列的 Pedine,我也必须克隆它,所以我这样做:
public class Pedine implements Cloneable{
private int x;
private int y;
private Piece pezzo;
private Colour colore;
...
@Override
public Pedine clone() throws CloneNotSupportedException{
return (Pedine) super.clone();
}
为什么不起作用?
我也试过这个代码,但它不起作用。
@Override
public Board clone() throws CloneNotSupportedException{
Board cloned = (Board) super.clone();
cloned.board = (Pedine[][]) board.clone();
for (int i=0; i<8; i++)
for(int j=0; j<8; j++){
cloned.board[i][j] = board[i][j].clone();
}
return cloned;
}
(Pedine extends Object)
多维数组的深度克隆应该自定义编码,如解释的那样here
正如 sharonbn 指出的那样,问题出在双数组中。虽然您可以使用双循环手动克隆它,但您的国际象棋引擎将遭受性能损失:您将克隆 lot 的棋盘,并且您可以从中受益更容易复制。
一个选择是使用平面数组和一些巧妙的寻址来加快速度:
private Piece[] board; // 64 Pieces in there
public Piece at(col, row) {
if (row < 0 || row >= 8 || col < 0 || col >= 8) return null;
return board[col + row*8];
}
现在,您使用 at(col, row)
而不是访问 board[row][col]
。并且复制和创建板更容易:
board = other.board.clone();
...现在应该可以正常工作了。
我还强烈建议使用不可变的部分,没有任何状态信息。例如,您当前的作品有一个 x
和 y
字段。他们要这些干什么?你应该只在移动它们时告诉它们它们的实际位置;这样,您根本不需要克隆棋子——因为所有棋子都完全一样,而且您实际上可以对所有与黑棋子相关的东西使用相同的 "black pawn"。
我在深度复制方面遇到了一些问题。 我有这个 java 项目,国际象棋,我需要使用 clone() 方法,因为我需要在不更改棋盘的情况下尝试新的配置。
Board scacchiera = new Board();
Initialization(scacchiera);
Board clone = scacchiera.clone();
System.out.println(scacchiera.toString());
System.out.println(clone.toString());
我创建了一个对象 scacchiera,然后克隆它。我认为我已经正确完成了深拷贝,但是当我在 scacchiera 中更改某些内容时,克隆也会更改。 在对象板中:
public class Board implements Cloneable{
//TODO
//rivedere se check e checkmate public o private;
//se private, costruire get e set;
public Pedine[][] board;
public boolean check;
public boolean checkmate;
//creating 2 lists for all the pieces; Neri=black, Bianchi=White
public ArrayList<Pedine> Neri;
public ArrayList<Pedine> Bianchi;
public Board(){
this.board = new Pedine [8][8];
this.check = false;
this.checkmate = false;
this.Neri = new ArrayList<Pedine>();
this.Bianchi = new ArrayList<Pedine>();
}
...
@Override
public Board clone() throws CloneNotSupportedException{
Board cloned = (Board) super.clone();
cloned.board = (Pedine[][]) board.clone();
return cloned;
}
我有这个双阵列的 Pedine,我也必须克隆它,所以我这样做:
public class Pedine implements Cloneable{
private int x;
private int y;
private Piece pezzo;
private Colour colore;
...
@Override
public Pedine clone() throws CloneNotSupportedException{
return (Pedine) super.clone();
}
为什么不起作用?
我也试过这个代码,但它不起作用。
@Override
public Board clone() throws CloneNotSupportedException{
Board cloned = (Board) super.clone();
cloned.board = (Pedine[][]) board.clone();
for (int i=0; i<8; i++)
for(int j=0; j<8; j++){
cloned.board[i][j] = board[i][j].clone();
}
return cloned;
}
(Pedine extends Object)
多维数组的深度克隆应该自定义编码,如解释的那样here
正如 sharonbn 指出的那样,问题出在双数组中。虽然您可以使用双循环手动克隆它,但您的国际象棋引擎将遭受性能损失:您将克隆 lot 的棋盘,并且您可以从中受益更容易复制。
一个选择是使用平面数组和一些巧妙的寻址来加快速度:
private Piece[] board; // 64 Pieces in there
public Piece at(col, row) {
if (row < 0 || row >= 8 || col < 0 || col >= 8) return null;
return board[col + row*8];
}
现在,您使用 at(col, row)
而不是访问 board[row][col]
。并且复制和创建板更容易:
board = other.board.clone();
...现在应该可以正常工作了。
我还强烈建议使用不可变的部分,没有任何状态信息。例如,您当前的作品有一个 x
和 y
字段。他们要这些干什么?你应该只在移动它们时告诉它们它们的实际位置;这样,您根本不需要克隆棋子——因为所有棋子都完全一样,而且您实际上可以对所有与黑棋子相关的东西使用相同的 "black pawn"。