简体   繁体   中英

How to deep clone an object list that contains several objects in java?

Say there is an EmployeeList that contains 5 Employee object.

I want to perform a clone of that EmployeeList to make a new EmployeeList, and I am wondering how should I do that?

So the following is my class Employee:

public class Employee {
private String name;
private String ssn;
private double salary;

private String name() {
    return name;
}

private void name(String name) {
    this.name = name;
}

private String ssn() {
    return ssn;
}

private void ssn(String ssn) {
    this.ssn = ssn;
}

private double salary() {
    return salary;
}

private void salary(double salary) {
    this.salary = salary;
}

void initialize(String initName, String initSsn, double initSalary) {
    this.name(initName);
    this.ssn(initSsn);
    this.salary(initSalary);
}

public Employee(String name, String ssn, double salary) {
    this.initialize(name, ssn, salary);
}

public Employee clone() {
    return new Employee(this.name, this.ssn, this.salary);
}
}

And the following is my class EmployeeList:

public class EmployeeList implements Cloneable {
private Employee[] list;
private int MAX = 5;

public EmployeeList() {
    list = new Employee[MAX];
    for (int i = 0; i < MAX; i++)
        list[i] = null;
}

public void add(Employee employee) {
    list[count] = employee;
}

public Object clone() {
    try {
        return super.clone();
    } catch (CloneNotSupportedException c) {
        System.out.println(c);
        return null;
    }
}   
}

I shorten the code so it`s easier to see.

My problem is:

When I performed the copy, I think that it copied the EmployeeList with pointers that points to the original Employee objects. Because when I change the original objects, the one in the new list changes as well

Is there anyway I can get that fixed?

Thank you very much.

yup, it did exactly what you thought it did - it cloned your array including its values. the array values in this case are pointers to instances of Employee, so you got a 2nd array pointing to the same Employees. its called a shallow copy. if you want a full copy you need something like

public Object clone() {
    try {
        EmployeeList copy = (EmployeeList) super.clone();
        if (list!=null) {
            copy.list = new Employee[list.length];
            for (int i=0; i<list.length; i++) {
                copy.list[i] = (Employee)list[i].clone();
            }
        } else {
            copy.list = null;
        }
        return copy;
    } catch (CloneNotSupportedException c) {
        System.out.println(c);
        return null;
    }
}

you will also need to make Employee clonable. generally when youre dealing with a graph of objects each object's clone() method needs to recursively clone its data members until you hit primitives (like your double ) or immutable classes (classes that cannot be changed once constructed - like String in your case)

in your EmployeeList.cone() , insted of calling super.clone() , which does shallow copy, you should instead iterate over the list elements and called clone() on each Employee object, like pseudocode below:

EmployeeList.clone() {
   EmployeeList newList = (EmployeeList) super.clone();
   int i=0;
   for (Employee emp: this.list){
      newList[i++] = (Employee) emp.clone();
   }
   return newList;
}

Other option, without using Cloneable is to use Serializable interface and use a utility like Apache commons SerializationUtils to deep clone the object http://commons.apache.org/lang/api-2.3/org/apache/commons/lang/SerializationUtils.html#clone%28java.io.Serializable%29

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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