Reputation: 47
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.
Upvotes: 0
Views: 3088
Reputation: 24212
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)
Upvotes: 1
Reputation: 1504
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
Upvotes: 0