【问题标题】:Deep copy (clone) of an object with matrix (Java)带有矩阵的对象的深拷贝(克隆)(Java)
【发布时间】:2015-05-28 13:26:04
【问题描述】:

我在深度复制方面遇到了一些麻烦。 我有这个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;
}

我有这个 Pedin 的双数组,我也必须克隆它,所以我这样做了:

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 扩展对象)

【问题讨论】:

  • Pedine 的超类是什么?是对象吗?
  • 什么是PieceColour 是什么?它们都是枚举(应该是)还是不同的东西?
  • 是的,两个枚举。这是存储库中的所有内容

标签: java clone deep-copy


【解决方案1】:

多维数组的深度克隆应该是自定义编码的,正如here所解释的那样

【讨论】:

  • 我试过了,但没用。我在第一篇文章中添加了代码。
  • 如果我修改第一个对象,“深度克隆”对象也会发生变化,这是不应该的。
  • 什么修改?在矩阵中?
  • 是的。我在矩阵 A 上更改了一块,在矩阵 A 和矩阵 B 上更改了一块。我也尝试使用 clone() 方法进行复制,只是复制,但仍然不起作用。我开始认为问题出在矩阵上的一组变化......
【解决方案2】:

正如 sharonbn 所指出的,问题出在双数组中。虽然您可以使用双循环手动克隆它,但您的国际象棋引擎将遭受性能损失:您将克隆大量棋盘,并且您可以从使它们更容易复制中受益到处复制。

一种选择是使用平面数组和一些巧妙的寻址来加快速度:

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

现在,您无需访问board[row][col],而是使用at(col, row)。而且复制和创建板子要容易得多:

board = other.board.clone(); 

... 现在应该可以按预期工作了。

我还强烈建议使用不可变的片段,没有任何状态信息。例如,您当前的作品有一个 xy 字段。他们需要这些做什么?您应该只在移动它们时告诉它们它们的实际位置;这样,您根本不需要克隆棋子——因为所有棋子都完全相同,并且您实际上可以对所有与黑棋子相关的事物使用相同的“黑棋子”。

【讨论】:

  • 我试过了,还是不行,克隆的对象也变了。顺便说一句,我使用双数组更容易。
  • 我无法更改这些片段,因为我使用它们的字段,例如 x、y 和颜色,来检查它们的移动是否合法。如果我改变,我必须重写一切:(
  • 编写一个高效的国际象棋引擎很难——这只是表面问题。有一种叫做“位板”的东西可以显着提高速度以换取阅读难度。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-05
  • 2011-03-24
  • 2012-10-17
  • 2019-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多