clone(): ArrayList.clone() I thought does a shallow copy

China☆狼群 提交于 2019-11-26 17:43:51

问题


ArrayList<Integer> a=new ArrayList<Integer>();
a.add(5);
ArrayList<Integer> b=(ArrayList<Integer>)a.clone();
a.add(6);
System.out.println(b.toString());

In the above piece of code, i think clone() does a shallow copy. So, b and a should point to the same memory location. However, when i do b.toString(), the answer is only 5. Why is 6 also not displayed if clone() does a shallow copy?


回答1:


Shallow copy does not mean that they point to the same memory location. That would be just an assignment:List b = a;.

Cloning creates a new instance, holding the same elements. This means you have 2 different lists, but their contents are the same. If you change the state of an object inside the first list, it will change in the second list. (Since you are using an immutable type - Integer - you can't observe this)

However, you should consider not using clone(). It works fine with collections, but generally it's considered broken. Use the copy-constructors - new ArrayList(originalList)




回答2:


If it was like you thought, then the clone method would be completely useless, because in that case, the following lines would be equivalent:

ArrayList<Integer> b = (ArrayList<Integer>)a.clone();
ArrayList<Integer> b = a;

Cloning is - like in real world scenarios - a process of creating two entities with exactly the same properties (at the time of the cloning operation).

And as Bozho mentioned - avoid the Java clone() concept. Even it's author mentioned, that it is broken.

This question and it's answers are quite valuable and provide a link to Josh Blochs own comments on his piece of work ;-)




回答3:


This indeed does a shallow copy, here is a comment for clone, from ArrayList source code

Returns a shallow copy of this ArrayList instance. (The elements themselves are not copied.)

To understand this, let's look at a snippet in clone method from ArrayList

v.elementData = Arrays.copyOf(elementData, size);

As we know, when we assign an Object to a variable, JAVA does not make a brand new copy of that Object. Instead, this variable becomes another reference pointing to the original Object.

Thus, elementData are actually storing reference to objects put into this ArrayList. And clone just copy these references, no replicas of Objects are created.

Of course, you can remove or add new reference to a cloned ArrayList.

However, modification of old Objects in one ArrayList will effect the original ArrayList. It's hard to do illustration with your example since Integer is immutable.

To see the side effect, you can define a custom mutable Object

class Person {
        private int a;

        public void setA(int a) {
            this.a = a;
        }
        public int getA() {
            return a;
        }
        @Override
        public String toString() {
            return String.valueOf(a);
        } 
   } 

Then you can use the following code to make test

        Person p1 = new Person();
        Person p2 = new Person();

        ArrayList<Person> tt = new ArrayList<Person>();
        tt.add(p1);
        tt.add(p2);

        ArrayList<Person> yy = (ArrayList<Person>) tt.clone();
        Person vv = yy.get(yy.indexOf(p2));
        vv.setA(12);
        yy.remove(p1);

        System.out.println("tt: " + tt);
        System.out.println("yy: " +yy);

The output should be

tt: [0, 12]
yy: [12]

See the side effect :) ? We only change the element in yy, but it is also reflected in tt.




回答4:


Shallow Cloning is the default cloning strategy provided by Object.clone() which you are talking about. The clone() method of object class creates a new instance and copy all fields of the Cloneable object to that new instance (either it is primitive or reference). So in the case of reference types only reference bits gets copied to the new instance, therefore, the reference variable of both objects will point to the same object. The example we have seen above is an example of Shallow Cloning.

Deep Cloning As the name suggest deep cloning means cloning everything from one object to another object. To achieve this we need to trick our clone() method to provide our own cloning strategy. We can do it by implementing Cloneable interface and override clone() method in every reference type we have in our object hierarchy and then call super.clone() and these clone() methods in our object’s clone method.

But if you look at the clone() method of ArrayList in the source code, you will see it is externally copying v.elementData = Arrays.copyOf(elementData, size); after calling super.clone(), which means clone() of ArrayList deeply copies it content

public Object clone() {
    try {
        ArrayList<?> v = (ArrayList<?>) super.clone();
        v.elementData = Arrays.copyOf(elementData, size);
        v.modCount = 0;
        return v;
    } catch (CloneNotSupportedException e) {
        // this shouldn't happen, since we are Cloneable
        throw new InternalError(e);
    }
}

To read more about Cloning and its types like deep cloning and shallow cloning please read Java Cloning and Types of Cloning (Shallow and Deep) in Details with Example




回答5:


can't we select dynamically at what position we want to add the string like this

int r=k.nextInt();
Integer i6=new Integer(r);
System.out.println("Enter the address");
String p6=k.nextLine();
ar3.add(i6,p6);

its not excuting the after reading the integer




回答6:


clone function in Arraylist is not same as copying one arraylist to another, If we use clone(), it holds the copy of original arraylist, but if we make any change to the original arraylist after use clone(), It will not affect the copyed arraylist.. Eg:

public static void main(String[] a) {

List list = new ArrayList();

list.add("A");

List list2 = ((List) ((ArrayList) list).clone());

System.out.println(list);
System.out.println(list2);

list.clear();

System.out.println(list);
System.out.println(list2);
}

Output:-

[A]

[A]

[ ]

[A]



来源:https://stackoverflow.com/questions/4592478/clone-arraylist-clone-i-thought-does-a-shallow-copy

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!