Java 深度克隆包含 ArrayLists 的对象
Java Deepcloning an object that contains ArrayLists
我有一个名为 Board 的 class,其中包含以下内容
public class Board {
protected Piece[][] GameBoard = new Piece[8][8];
ArrayList<Move> BlackBoardmoves = new ArrayList<Move>();
ArrayList <Move> WhiteBoardmoves = new ArrayList<Move>();
我想创建一个全新的 Board 对象,它有 2 个完全独立的 ArrayList
几天来我一直在阅读有关如何执行此操作的信息,并且尝试了各种方法,例如实施克隆或可序列化。
我读到 clone 接口坏了而且使用 serializable 会慢很多所以我决定写我自己的复制方法
void copy(Board c)
{
for(int i =0; i<8; i++)
{
for(int j=0; j<8; j++)
{
this.GameBoard[i][j] = c.GameBoard[i][j];
}
}
for(int i=0 ;i<c.BlackBoardmoves.size(); i++)
{
this.BlackBoardmoves.add(c.BlackBoardmoves.get(i));
}
for(int i=0 ;i<c.WhiteBoardmoves.size(); i++)
{
this.WhiteBoardmoves.add(c.WhiteBoardmoves.get(i));
}
}
我在创建每个新对象时正在做的是这个
Board obj2 = new Board();
obj2.copy(obj1);
这只是我项目的一小部分,所以我已经坚持了好几天,真的不能花更多的时间在这上面。非常感谢:)
你究竟想在这里做什么?
你想要副本有多深?
您只是将旧列表的内容复制到新列表中,这可能(对于适当的深层复制)不是您想要的。
您也在以一种相当低效的方法进行操作,为什么不使用列表 class 的 "addAll" 方法呢?
但您可能还想创建列表条目的副本,并且可能比这更深...
由于您未在此处说明您的要求,因此无法确定。
首先,我建议使 Move
和 Piece
对象 不可变 。使用这种方法,您只需要复制对这些对象的引用而无需深度克隆。
private static <T> void copy2DArray(T[][] to, T[][] from) {
for (int i = 0; i < to.length; i++)
for (int j = 0; j < to[i].length; j++) {
to[i][j] = from[i][j];
}
}
void copy(Board c) {
copy2DArray<Piece>(this.GameBoard, c.GameBoard);
this.BlackBoardmoves = new ArrayList(c.BlackBoardmoves);
this.WhiteBoardmoves = new ArrayList(c.WhiteBoardmoves);
}
在 Board class 内部,您可以放置将 return 复制对象的方法,但您将需要适当的构造函数。您还必须在 Piece class 中添加相同的方法来深度复制数组中的每个对象。
Board(Object[][] GameBoard, ArrayList<Object> BlackBoardObjects, ArrayList <Object> WhiteBoardObjects){
this.GameBoard = GameBoard;
this.BlackBoardObjects = BlackBoardObjects;
this.WhiteBoardObjects = WhiteBoardObjects;
}
public Board getCopy(){
for(int i = 0; i < GameBoard.length; i++){
for(int j = 0; j < GameBoard[0].length; j++){
GameBoardCopy[i][j] = GameBoard[i][j].getCopy();
}
}
ArrayList<Move> BlackBoardObjectsCopy = new ArrayList<Move>(BlackBoardObjects);
ArrayList <Move> WhiteBoardObjectsCopy = new ArrayList<Move>(WhiteBoardObjects);
return new Board(GameBoard, BlackBoardObjectsCopy, WhiteBoardObjectsCopy);
}
我有一个名为 Board 的 class,其中包含以下内容
public class Board {
protected Piece[][] GameBoard = new Piece[8][8];
ArrayList<Move> BlackBoardmoves = new ArrayList<Move>();
ArrayList <Move> WhiteBoardmoves = new ArrayList<Move>();
我想创建一个全新的 Board 对象,它有 2 个完全独立的 ArrayList 几天来我一直在阅读有关如何执行此操作的信息,并且尝试了各种方法,例如实施克隆或可序列化。 我读到 clone 接口坏了而且使用 serializable 会慢很多所以我决定写我自己的复制方法
void copy(Board c)
{
for(int i =0; i<8; i++)
{
for(int j=0; j<8; j++)
{
this.GameBoard[i][j] = c.GameBoard[i][j];
}
}
for(int i=0 ;i<c.BlackBoardmoves.size(); i++)
{
this.BlackBoardmoves.add(c.BlackBoardmoves.get(i));
}
for(int i=0 ;i<c.WhiteBoardmoves.size(); i++)
{
this.WhiteBoardmoves.add(c.WhiteBoardmoves.get(i));
}
}
我在创建每个新对象时正在做的是这个
Board obj2 = new Board();
obj2.copy(obj1);
这只是我项目的一小部分,所以我已经坚持了好几天,真的不能花更多的时间在这上面。非常感谢:)
你究竟想在这里做什么? 你想要副本有多深? 您只是将旧列表的内容复制到新列表中,这可能(对于适当的深层复制)不是您想要的。 您也在以一种相当低效的方法进行操作,为什么不使用列表 class 的 "addAll" 方法呢?
但您可能还想创建列表条目的副本,并且可能比这更深... 由于您未在此处说明您的要求,因此无法确定。
首先,我建议使 Move
和 Piece
对象 不可变 。使用这种方法,您只需要复制对这些对象的引用而无需深度克隆。
private static <T> void copy2DArray(T[][] to, T[][] from) {
for (int i = 0; i < to.length; i++)
for (int j = 0; j < to[i].length; j++) {
to[i][j] = from[i][j];
}
}
void copy(Board c) {
copy2DArray<Piece>(this.GameBoard, c.GameBoard);
this.BlackBoardmoves = new ArrayList(c.BlackBoardmoves);
this.WhiteBoardmoves = new ArrayList(c.WhiteBoardmoves);
}
在 Board class 内部,您可以放置将 return 复制对象的方法,但您将需要适当的构造函数。您还必须在 Piece class 中添加相同的方法来深度复制数组中的每个对象。
Board(Object[][] GameBoard, ArrayList<Object> BlackBoardObjects, ArrayList <Object> WhiteBoardObjects){
this.GameBoard = GameBoard;
this.BlackBoardObjects = BlackBoardObjects;
this.WhiteBoardObjects = WhiteBoardObjects;
}
public Board getCopy(){
for(int i = 0; i < GameBoard.length; i++){
for(int j = 0; j < GameBoard[0].length; j++){
GameBoardCopy[i][j] = GameBoard[i][j].getCopy();
}
}
ArrayList<Move> BlackBoardObjectsCopy = new ArrayList<Move>(BlackBoardObjects);
ArrayList <Move> WhiteBoardObjectsCopy = new ArrayList<Move>(WhiteBoardObjects);
return new Board(GameBoard, BlackBoardObjectsCopy, WhiteBoardObjectsCopy);
}