-2

I just read about deep copy of ArrayList, that people think

new ArrayList<>(originalList);

will create a shallow copy. And I wrote a small demo

    ArrayList<String> originalNameList = new ArrayList<>(Arrays.asList("Anna", "Betty", "Chris"));
    List<String> copyNameList1=originalNameList;
    List<String> copyNameList2= new ArrayList<>(originalNameList);

    originalNameList.add("Duke");
    copyNameList1.add("Ellen");
    copyNameList1.set(1,"Bill");
    copyNameList2.set(0,"Andy");

    System.out.println("originalNameList = " + originalNameList);
    System.out.println("copyNameList1    = " + copyNameList1);
    System.out.println("copyNameList2    = " + copyNameList2);

The result:

originNameList = [Anna, Bill, Chris, Duke, Ellen]
copyNameList1  = [Anna, Bill, Chris, Duke, Ellen]
copyNameList2  = [Andy, Betty, Chris]

I feel that copy constructor of ArrayList is not that shallow. That why people say that so? Are there some levels of deep copy? Thank a lot!

Huy Hóm Hỉnh
  • 597
  • 7
  • 18
  • 1
    The result is exactly as if shallow copy was executed. What is your expected output, and why? – user202729 Jul 14 '18 at 09:05
  • 5
    You seem to have a different definition of shallow and deep. A shallow copy means that only references to the objects inside the list are copied. That's what happens. A deep copy means that the objects inside the list themselves are copied (i.e. cloned if you prefer), and that the copies would be stored into the new list. – JB Nizet Jul 14 '18 at 09:06
  • 1
    In Java instances of the String class are supposed to be immutable. How would you observe the difference between a shallow and a deep copy of a collection of immutable objects? – PeterT Jul 14 '18 at 09:07
  • 2
    @PeterT With `==`... – user202729 Jul 14 '18 at 09:08
  • @PeterT Got it, demo should be go with mutable object, tks – Huy Hóm Hỉnh Jul 14 '18 at 09:35

1 Answers1

4

Your definitions for "shallow" and "deep" copy seem to be wrong. It seems like you think a shallow copy means "copying the reference to the object", like this:

List<String> copyNameList1=originalNameList;

Whereas a "deep" copy creates a new array list:

List<String> copyNameList2= new ArrayList<>(originalNameList);

Note that the above is a misconception.

A shallow copy actually means creating a new array list with the same elements, while a deep copy means creating a new array list that has copies of the elements in the original array list.

The big difference here is "whether the elements in the array list are copied".

Imagine you have an array list object a1. It contains references to 3 three objects obj1, obj2, obj3.

A shallow copy of a1 will create a new array list object a2 that contains references to the same obj1, obj2, obj3 objects.

A deep copy of a1 will create a new array list object a2 that contains references to obj4, obj5, obj6, where obj4, obj5 and obj6 are copies of obj1, obj2, and obj3 respectively.

Here are two methods that shows what happens in shallow copy and deep copy:

static ArrayList<String> shallowCopy(ArrayList<String> original) {
    ArrayList<String> copy = new ArrayList<>();
    for (String s : original) {
        copy.add(s);
    }
    return copy;
}

static ArrayList<String> deepCopy(ArrayList<String> original) {
    ArrayList<String> copy = new ArrayList<>();
    for (String s : original) {
        String copyOfString = new String(s); // note that each string is copied as well
        copy.add(copyOfString);
    }
    return copy;
}

In general, a deep copy copies the objects that the target object refers to as well.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • My mistake is creating a sample with String type, it's immutable type. I just create other with object type and see it clear as you told. Tks a lot! – Huy Hóm Hỉnh Jul 14 '18 at 09:41