3

NOTE: I have looked at different places including stackoverflow and have not found solution to this.

PROBLEM:

class Animal{

AnimalGroup animalGroup;

}

class AnimalGroup{

List<Animal> animalList;

}

class MainProgram{

// Map<groupRank, animalGroup>
Map<Integer, AnimalGroup> rankedAnimalGroups;

}

Note: As it is apparent one Animal can belong to only one AnimalGroup.

I want to deep copy the map rankedAnimalGroups.

Case1: Cloning

I will make my Animal and AnimalGroup Cloneable.

Clone method in AnimalGroup

protected Object clone() throws CloneNotSupportedException {
    AnimalGroup clonedAnimalGroup = (AnimalGroup)super.clone();
    for(Animal animal: animalList)
       clonedAnimalGroup.addAnimal(animal.clone);

    return clonedAnimalGroup;
}

Clone method in Animal

protected Object clone() throws CloneNotSupportedException {
    Animal clonedAnimal = (Animal)super.clone();
    clonedAnimal.animalGroup = animalGroup.clone(); 
}

This will end up in a cycle of AnimalGroup calling Animal and reverse.

Case2: copyConstructor

HashMap doesnot support deep copy constructor

Suggested Solution

I can use constructor for Animal, inside clone method of AnimalGroup, as follows

Clone method in AnimalGroup

protected Object clone() throws CloneNotSupportedException {
    AnimalGroup clonedAnimalGroup = (AnimalGroup)super.clone();
    for(Animal animal: animalList)
       clonedAnimalGroup.addAnimal(new Animal(animal, this));

    return clonedAnimalGroup;
}

Constructor in Animal

public Animal(Animal other, AnimalGroup animalGroup)
{
  this.animalGroup = animalGroup;
  ...
}

Question Is there any better solution for deep copy in such case.

Edit1

Data size is too large for serialization related approach.

Edit2

I can not include external libs etc for copying in my project

varsh
  • 152
  • 10
  • Kind of duplicate: http://stackoverflow.com/questions/13049222/java-hashmap-deep-copy – tilpner Nov 21 '13 at 09:23
  • The problem in above question is not how to copy hashmap. It is about how to resolve the issue for recursive calling to each other of the two classes in their clone methods – varsh Nov 21 '13 at 09:25

2 Answers2

2

You can give yourself the helper methods you need to perform a deep copy. When deep-copying an Animal, obtain a deep copy of its group instead and return the member of that group corresponding to the Animal being copied; when deep-copying a group, obtain new copies of the members without assigning them any group, add these new copies to a new list, assign that list as the group for each element, then return the new list. Doing so will require that the group have access to a special constructor that does not assign a group right away.

There are other similar variations on this theme.

Judge Mental
  • 5,209
  • 17
  • 22
  • Thats a good answer. Your answer would have been perfect for a situation where Animal and AnimalGroup would have one-on-one relation, instead of List. Anyways, thanks I will try this. Just curious, did you come up with the answer just now or is this like a normal practice in such situations? – varsh Nov 21 '13 at 20:09
  • Should work even in one-to-many case. You just need a `deepCopyExceptGroup` available in the `Animal` class. I just came up with it on the fly but this type of algorithm arises all the time with circular data. It reminds me of something I learned about in a programming languages course from undergraduate school. I'll see if I can find the reference. – Judge Mental Nov 22 '13 at 00:45
  • A reference would be great, thanks. Between, I understand that your solution will be good for one-to-many as well, in fact I will use a similar variation, I was just pointing about one-on-one case. – varsh Nov 22 '13 at 02:42
1

You can serialize-deserialize the object which is robust way of deep cloning

Community
  • 1
  • 1
sanbhat
  • 17,522
  • 6
  • 48
  • 64