user3016421
user3016421

Reputation: 119

When to use clone() and how actually addAll() and add() works

I am using Java with MySQL.

There are about 60 transactions screens are there in my project. I had used add() and addAll() functions to copy an ArrayList.

For example:

 List<Bean> a1 = new ArrayList<Bean>(); // and add some value      
 List<Bean> a2 = new ArrayList<Bean>(); 
 a2.addAll(a1);

In this case:

  1. In most of the screens, there is no any issue on add() or addAll() functions, but for some screens, if made change on list a2 it also affects the a1 list.
  2. In these particular screens, clone concept (implements Cloneable interface) is used to get rid from it and its working fine.

According to my study, add() functions sets only reference to destinations list.

My doubts are:

  1. Why clone() is required (For some cases only and not in all)?
  2. What happens actually if we add() or addAll() a list into another list?
  3. Whether, clone() is mandatory for add() or addAll() methods or not?
  4. Where we should use clone() and where shouldn't?
  5. What should happen to list a1 if we made any changes in list a2?

My final question:

When to use clone() or copy constructor and when we need not to use. And in generic List, what should happen to source list if we made changes in target list like above example.

Upvotes: 3

Views: 3065

Answers (2)

Alex Pruss
Alex Pruss

Reputation: 534

It sounds like you want to add a copy of the objects of one list to another list. As Eran said, simply calling add() or addAll() isn't going to be enough, since this copies references.

To add to Eran's answer - it sounds like you think calling clone() is going to solve your problem, but that's only true if you've implemented a custom clone function! The default clone() only creates a shallow copy, meaning that any references contained in the cloned object are copied over.

Generally speaking, I find copy constructors or factory methods much easier and safer than clone().

Upvotes: 0

Eran
Eran

Reputation: 393781

Yes, addAll adds all the references of the source List to the target List. It doesn't create copies of the instances these references refer to.

This is sufficient when the List holds references to immutable objects. If you add or remove elements from one of the Lists after the addAll operation, the changes won't be reflected in the other List.

If the List holds references to mutable objects, and you are modifying the state of those objects, you must create copies (either using clone or a copy constructor) if you don't want changes in one List to be reflected in the other List.

BTW, passing a List to add (instead of to addAll) will add a reference of the List to the target List. Unless the target List is a List of Lists, you shouldn't do that. add should accept a single element to be added to the List.

Upvotes: 3

Related Questions