0

Possible Duplicate:
How to clone ArrayList and also clone its contents?

I have a ArrayList<Widget> that I would like to "deep" clone so that making modifications to any items in the original list does not have any effect on the items in the cloned list:

ArrayList<Widget> origList = getMyList();
ArrayList<Widget> cloneList = origList.clone();

// Remove the 5th Widget from the origina list
origList.remove(4);

// However, the cloneList still has the 5th Widget and is unchanged

// Change the id of the first widget
origList.get(0).setId(20);

// However in cloneList, the 1st Widget's ID is not 20

What's the best/safest way of accomplishing this? I imagine that it's not as simple as:

ArrayList<Widget> cloneList = origList.clone();

I imagine the fact that this is a built-in ArrayList type, plus the fact that its generic, are going to complicate things. I also imagine I will need to write a special clone() override for my Widget class?

Thanks in advance!

Edit:
I'd also be completely receptive if there is a commons JAR out there that does this heavy lifting for me, so please feel free to make suggestions, however I would still like to know how to do this the ole' fashion way so I can learn ;-)

Community
  • 1
  • 1
IAmYourFaja
  • 55,468
  • 181
  • 466
  • 756

4 Answers4

5

This is a non-trivial task, I suggest you use one of the available libraries such as http://code.google.com/p/cloning/

See also: Java: recommended solution for deep cloning/copying an instance

If you want to see how it's done get an open-source library and look at the source :)

Community
  • 1
  • 1
xpapad
  • 4,376
  • 1
  • 24
  • 25
4

You need to iterate over each item in the original list and clone each item individually, then add them to a new list of 'cloned' items.

Something like:

List<Widget> origList = getMyList();
List<Widget> clonedList = clone(origList);

private List<Widget> clone(List<Widget> listToClone) {
  List<Widget> clonedList = new LinkedList<Widget>();

  for (Widget widget : listToClone) {
    clonedList.add(widget.clone());
  }

  return clonedList;
}

For this to work you will have to have your Widget object implement the Cloneable interface, and the clone() method. Nothing else is needed.

But again, as the other posters have said, many would argue that the clone implementation in Java isn't great to rely on, and is best avoided.

Cuga
  • 17,668
  • 31
  • 111
  • 166
2

Some authorities discourage the use of clone. Here is one link off google. That's not to say don't do it, but just be aware of what you are getting yourself into, and be sure to test (well, always do that).

I would probably put a deepCopy method on the root class, and just do the copy the brute force way, with copy constructors. A copy constructor is a constructor that takes an instance of the class in question, and creates a new instance, copying the internal state of the argument into the new instance.

hvgotcodes
  • 118,147
  • 33
  • 203
  • 236
1

You might want to take a look at this: http://code.google.com/p/cloning/

Web User
  • 7,438
  • 14
  • 64
  • 92