我创建了一个具有许多属性的对象,包括一个称为矩阵的锯齿状数组属性。
在我的脚本中,我想克隆对象的副本并将其放入对象的arraylist中。但是我无法正确设置矩阵属性的克隆副本,因为它会将最后一次已知的引用传递到我的列表中。代码
MatrixObject newMatrixObject = new MatrixObject();
List<MatrixObject> listMatrix = new ArrayList<MatrixObject>();
try { //some code here looking int text file
int[][] myArray = some value;
newMatrixObject.matrix = myArray; //this works but keeps changing to the last value of myArray
//I tried this as well
newMatrixObject.matrix = newMatrixObject.SetMatrix(myArray); // didnt work either and I tried setting it without returning an array, same story
listMatrix.add(new MatrixObject(newMatrixObject));
}
...对于对象类,我一直在做很多事情,但一般都是这个
public class MatrixObject
{
public Date startDate;
public int[][] matrix;
public MatrixObject (MatrixObject copy) {
this.startDate = copy.startDate;
this.matrix = copy.Matrix;
}
我也在课堂上创建了这个方法,但我认为它的工作
public int[][] SetMatrix(int[][] inputMatrix){
//if (inputMatrix == null){
//return null;
//}
int [][] result = new int [inputMatrix.length][];
for ( int i= 0; i< inputMatrix.length; i++)
{
result[i] = Arrays.copyOf(inputMatrix[i], inputMatrix[i].length);
}
System.out.println(Arrays.deepToString(result));
return result;
}
如果有更好的方法将对象的克隆添加到列表中,那么也可以。我很容易,只是想弄明白这件事。
答案 0 :(得分:4)
很难确切地说出你在做什么,但我认为问题是构造函数。
public MatrixObject (MatrixObject copy) {
this.startDate = copy.startDate;
this.matrix = copy.matrix;
}
这会使MatrixObject
与[{1}}的内部共享,因此您对新copy
所做的任何更改都会实际更改另一个MatrixObject
。相反,你应该复制所有字段,如下所示:
public MatrixObject (MatrixObject copy) {
this.startDate = new Date(copy.startDate.getTime());
this.matrix = new int[copy.matrix.length][];
for (int i = 0; i < copy.matrix.length; i++)
this.matrix[i] = Arrays.copyOf(copy.matrix[i], copy.matrix[i].length);
}
答案 1 :(得分:1)
使用new
后跟类名来复制对象通常会导致代码无法扩展。使用clone
,prototype pattern的应用程序是实现此目标的更好方法。但是,使用Java中提供的clone
也可能会有问题。
最好从clone
方法调用非公共拷贝构造函数。这使我们能够将创建对象的任务委托给类本身的实例,从而提供可扩展性,并使用非公共拷贝构造函数安全地创建对象。
以下是MatrixObject
课程的修改。它显示了如何通过依赖构建过程安全地实现clone
。 这在您的班级包含final
字段的情况下特别有用。
import java.util.*;
public class MatrixObject implements Cloneable {
private Date startDate;
private int[][] matrix;
public MatrixObject(Date newDate, int[][] newMatrix) {
this.startDate = newDate;
this.matrix = newMatrix;
}
protected MatrixObject(MatrixObject another) {
Date refDate = null;
int[][] refMatrix = null;
refDate = (Date) another.startDate.clone();
refMatrix = another.matrix.clone();
this.matrix = refMatrix;
this.startDate = refDate;
}
public void setMatrix(int[][] newMatrix) {
this.matrix = newMatrix;
}
public void setDate(Date newDate) {
this.startDate = newDate;
}
public String toString() {
String s = "";
for (int[] tmp : this.matrix) {
s += Arrays.toString(tmp) + "\n";
}
return String.format("%s%n%s", this.startDate.toString(), s);
}
@Override
public Object clone() {
return new MatrixObject(this);
}
// MAIN GOES HERE (or anywhere in this class that is outside of a method)
// static void main(String[] args) { ... }
}
public static void main(String[] args) {
String output = "";
Calendar dates = Calendar.getInstance();
Date dateOne = dates.getTime();
// offset day of the month by one day
dates.set(Calendar.DAY_OF_MONTH, dates.get(Calendar.DAY_OF_MONTH) + 1);
Date dateTwo = dates.getTime();
int[][] myArrayOne = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 }, };
int[][] myArrayTwo = { { 0, 0, 1 }, { 0, 1, 0 }, { 1, 0, 0 }, };
// create two MatrixObjects, an original and a copy
MatrixObject oneMO = new MatrixObject(dateOne, myArrayOne);
MatrixObject copyMO = (MatrixObject) oneMO.clone();
// show the contents of the original MatrixObject and its copy
output += String.format("First MatrixObject:%n%s%n", oneMO.toString());
output += String
.format("Copied MatrixObject:%n%s%n", copyMO.toString());
// alter the original MatrixObject
oneMO.setMatrix(myArrayTwo);
oneMO.setDate(dateTwo);
// show that alterations to the original MatrixObject did not
// effect the copy
output += String.format("Changed First MatrixObject:%n%s%n",
oneMO.toString());
output += String.format("Unchanged Copied MatrixObject:%n%s%n",
copyMO.toString());
System.out.println(output);
}
First MatrixObject: Mon Apr 20 21:29:14 EDT 2015 [1, 0, 0] [0, 1, 0] [0, 0, 1] Copied MatrixObject: Mon Apr 20 21:29:14 EDT 2015 [1, 0, 0] [0, 1, 0] [0, 0, 1] Changed First MatrixObject: Tue Apr 21 21:29:14 EDT 2015 [0, 0, 1] [0, 1, 0] [1, 0, 0] Unchanged Copied MatrixObject: Mon Apr 20 21:29:14 EDT 2015 [1, 0, 0] [0, 1, 0] [0, 0, 1]