David David - 8 days ago 6
Java Question

Deep clone of Object in Java

Hi Guys I have the following class

public class Person{
private Person parent;
private int position;
private List<Person> siblings;

public Person(Person person) {
if (this.parent != null) {
this.parent = new Person(person.parent);
} else {
this.parent = null;
}
this.position = person.position;
//this.siblings = person.siblings;
this.siblings = cloneList(person.siblings);
}
// End Constructor

// Start Methods and Functions
public static List<Person> cloneList(List<Person> persons) {
List<Person> clonedList = new ArrayList<Person>(persons.size());
if (persons != null) {
for (Person person : persons) {
clonedList.add(new Person(person));
}
}
return clonedList;
}
// End Methods and Functions
}


Since there are many relationships between the people, and in my case the siblings can also be parents and vice versa, I am ending up with a StackOverflowError.

I am creating a few hundred objects all with some relation to each other which is stored in the siblings list and parent variable. Then while processing I need to make a copy of the entire state and store that state in a list and continue processing the first state without effecting the cloned state and when the need arises again I need to create another clone of that state and add it to the same list. When I am done processing the first state I want to get the next state in the list (which has been created while processing the first list) and process this one. Again there will be states that need to be cloned and added to the list till the current state is completed and move to the next state till all states have been processed.

I have read quite a few suggestions both on stackoverflow and elsewhere however none seem to fit exactly what I want.

It seems like I am ending up in an endless recursive state with the constructor and the cloneList method.

I have come across the Cloneable Interface in Java however have read that is not the best thing to use.

Any ideas on how this can be solved or maybe you could direct me to the info I need would be highly appreciated.

Thanks.

Edit : Had an error when pasting and editing the code.
Changed :
this.parent = new Person(Person.parent);
to
this.parent = new Person(person.parent);

since it should be creating a new Person from the reference of the object being passed to the constructor.

Answer

What I have found that if you have very complex object that has several references with other object, to make a clone that object very difficult. Java clone method will not support you very elegantly. What I would do, make the object serialize and then deserialize. This will give you a perfect clone of that object.

class Person implements Serializable{

 // YOUR CODE GOES HERE...........

 public Person makeClone() throws IOException, ClassNotFoundException {
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    ObjectOutputStream out = new ObjectOutputStream(outputStream);
    out.writeObject(this);

    ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
    ObjectInputStream in = new ObjectInputStream(inputStream);
    Person copied = (Person) in.readObject();
    return copied;
}  

You mark the object Serializable and then write that in ByteArrayOutputStream. And then Deserialize.This will ensure you that you will get absolutely different object with the state. Do research on java Serializable. Because there is a certain way to serialize object.

Comments