将对象克隆到arraylist,java

时间:2015-04-21 00:11:42

标签: java object arraylist clone

我创建了一个具有许多属性的对象,包括一个称为矩阵的锯齿状数组属性。

在我的脚本中,我想克隆对象的副本并将其放入对象的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;
}

如果有更好的方法将对象的克隆添加到列表中,那么也可以。我很容易,只是想弄明白这件事。

2 个答案:

答案 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后跟类名来复制对象通常会导致代码无法扩展。使用cloneprototype pattern的应用程序是实现此目标的更好方法。但是,使用Java中提供的clone也可能会有问题。

最好从clone方法调用非公共拷贝构造函数。这使我们能够将创建对象的任务委托给类本身的实例,从而提供可扩展性,并使用非公共拷贝构造函数安全地创建对象。

以下是MatrixObject课程的修改。它显示了如何通过依赖构建过程安全地实现clone这在您的班级包含final字段的情况下特别有用。

MatrixObject类

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]