简体   繁体   English

将对象克隆到数组列表中,java

[英]Clone Object into array list, java

I have an object I created that has a number of properties, including a jagged array property, called matrix. 我创建了一个对象,该对象具有许多属性,包括锯齿状数组属性,称为矩阵。

In my script, I want to clone a copy of the object and place it into an arraylist of my object. 在我的脚本中,我想克隆对象的副本并将其放入对象的arraylist中。 however i am not able to get a cloned copy of the matrix property to set correctly, as it keeps passing the last known reference into my list. 但是我无法正确设置matrix属性的克隆副本,因为它会将最新的已知引用不断传递到我的列表中。 Code below 下面的代码

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

...and for the object class I have been doing a bunch of things, but generally this ...对于对象类,我一直在做很多事情,但是通常

public class MatrixObject 
{
    public Date startDate;
    public int[][] matrix;

    public MatrixObject (MatrixObject copy) {

        this.startDate = copy.startDate;
        this.matrix = copy.Matrix;
}

I also created this method in the class, but I dont think its working 我也在课堂上创建了这个方法,但是我认为它不起作用

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

If there is a better way to add a clone of the object into the list, that will work as well. 如果有更好的方法将对象的副本添加到列表中,那么该方法也将起作用。 I am easy, just trying to figure this thing out. 我很容易,只是想弄清楚这件事。

It's hard to tell exactly what you are doing, but I think the problem is the constructor. 很难确切说明您在做什么,但我认为问题在于构造函数。

public MatrixObject (MatrixObject copy) {

    this.startDate = copy.startDate;
    this.matrix = copy.matrix;
}

This makes a MatrixObject that shares the internals of copy , so any changes you make to either to the new or the old MatrixObject will actually change the other one. 这将使MatrixObject共享copy的内部信息,因此您对新MatrixObject或旧MatrixObject任何更改实际上都会更改另一个。 Instead you should copy all of the fields, like this: 相反,您应该复制所有字段,如下所示:

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

Using new followed by the class name to copy an object often leads to code that is not extensible. 使用后跟类名的new复制对象通常会导致代码不可扩展。 Using clone , the application of the prototype pattern , is a better way to achieve this. 使用clone原型模式的应用)是一种更好的方法。 However, using clone as it is provided in Java can be problematic as well. 但是,使用Java中提供的clone也可能会产生问题。

It is better to invoke a non-public copy constructor from the clone method. 最好从clone方法中调用非公共副本构造函数。 This gives us the ability to delegate the task of creating an object to an instance of a class itself, thus providing extensibility and also, safely creating objects using the non-public copy constructor. 这使我们能够将创建对象的任务委托给类本身的实例,从而提供可扩展性,并且还可以使用非公共副本构造函数安全地创建对象。

Below is a reworking of your MatrixObject class. 下面是对MatrixObject类的重做。 It shows how you can implement clone safely by relying on the construction process. 它显示了如何依靠构建过程来安全地实现clone This is especially useful in cases where your class contains final fields. 这在班级包含final字段的情况下尤其有用。

MatrixObject Class 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) { ... }

}

Main Method 主要方法

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

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]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM