Search code examples
javalistarraylistclonecloning

How does ArrayList.clone() method work in Java?


I'm confused about the concept of cloning in Array lists. E.g :

Balloon green = new Balloon("Green",new Address("greenState", "greencity"));
Balloon green2 = (Balloon)green.clone();
green.setColor("NewGreen");
System.out.println(green);
System.out.println(green2);//color not affected in copy as color is of String type.
                           //Immutable objects are not shallow copied.
green.getAddress().state="helloState";
System.out.println(green);
System.out.println(green2);//Address does get affected

Output:-

Balloon[color = NewGreen Address = Address {state = greenState, city = greencity}]
Balloon[color = Green Address = Address {state = greenState, city = greencity}]
Balloon[color = NewGreen Address = Address {state = helloState, city = greencity}]
Balloon[color = Green Address = Address {state = helloState, city = greencity}]


So this I'm clear. But now lets take array lists.

Balloon red = new Balloon("Red",new Address("redState", "redCity")); 
Balloon blue = new Balloon("Blue",new Address("blueState", "blueCity"));
Balloon yellow = new Balloon("yellow",new Address("yellowState", "yellowCity"));

ArrayList<Balloon> list = new ArrayList<>();
list.add(red);
list.add(blue);
list.add(yellow);
ArrayList<Balloon> listCopy = (ArrayList<Balloon>)list.clone();
Balloon green = new Balloon("Green",new Address("greenState", "greencity"));

list.get(1).setColor("color");

list.add(green);
System.out.println(list);
System.out.println(listCopy);

Output:-

[Balloon[color = Red Address = Address {state = redState, city = redCity}], Balloon[color = color Address = Address {state = blueState, city = blueCity}], Balloon[color = yellow Address = Address {state = yellowState, city = yellowCity}], Balloon[color = Green Address = Address {state = greenState, city = greencity}]],

[Balloon[color = Red Address = Address {state = redState, city = redCity}], Balloon[color = color Address = Address {state = blueState, city = blueCity}], Balloon[color = yellow Address = Address {state = yellowState, city = yellowCity}]]

So in the above output, changing the color of a balloon in a list affects the copy as well. But adding a new element does not reflect in the copy.

Can someone explain this?


Based on luk2302's answer, the following visualization explains what is going on:

    list   object  listCopy
     |___  red   ___|
     |___  blue  ___|
     |___ yellow ___|


     list.add(green);
    list  object  listCopy
     |___  red   ___|
     |___  blue  ___|
     |___ yellow ___|
     |___ green 


     list.remove(blue);
    list  object  listCopy
     |___  red   ___|
           blue  ___|
     |___ yellow ___|
     |___ green 

Solution

  • clone on a ArrayList does not perform a deep copy / deep clone, in fact it performs a shallow one, meaning it does not copy the things it contains, it just copies the references to those elements.
    You still have only one green, blue and yellow balloon each. You have one list referencing four balloons and one list referencing three, the lists are independent from each other in terms of how many elements they contain. But the actual balloons they currently point to are shared.