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

后端 未结 6 1727
别那么骄傲
别那么骄傲 2020-11-29 05:59
ArrayList a=new ArrayList();
a.add(5);
ArrayList b=(ArrayList)a.clone();
a.add(6);
System.out.println(b.t         


        
相关标签:
6条回答
  • 2020-11-29 06:23

    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 ;-)

    0 讨论(0)
  • 2020-11-29 06:25

    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.

    0 讨论(0)
  • 2020-11-29 06:27

    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

    0 讨论(0)
  • 2020-11-29 06:33

    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)

    0 讨论(0)
  • 2020-11-29 06:33

    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]

    0 讨论(0)
  • 2020-11-29 06:45

    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

    0 讨论(0)
提交回复
热议问题