Java shallow copy, not working as expected

Sam :

This is probably very trivial to many of you, but I could not find the answer to it. Thanks in advance for any help.

In short, I shallow copy a list, then modify one of its elements, but the change is not reflected in the other list, despite almost every resource saying that they are just two references to the same object, and any change in one should be reflected in the other one.

P.S. I have already checked out questions like this one that clarify the differences b/w shallow and deep copy. My question is why despite those theories, sometimes shallow-copy behaves like deep-copy.

    List<Integer> lst1 = new ArrayList<>();
    lst1.add(2);
    lst1.add(6);
    lst1.add(1);
    lst1.add(4);
    lst1.add(9);
    lst1.add(5);

    List<Integer> lst2 = new ArrayList<>(lst1);
    lst1.set(0, 3);

    System.out.println("lst1 = " + lst1);
    System.out.println("lst2 = " + lst2);

result:

lst1 = [3, 6, 1, 4, 9, 5]

lst2 = [2, 6, 1, 4, 9, 5]

Louis Wasserman :

What you have is a shallow copy, yes, but any copy will show the change you describe. If it weren't a copy at all, it'd show that change, e.g. List<Integer> lst2 = lst1;.

The difference between a shallow and a deep copy is what happens to mutable elements in the array. Here is an example that shows the difference between a shallow and a deep copy.

List<List<Integer>> lst1 = new ArrayList<>();
lst1.add(new ArrayList<>(Arrays.asList(5)));
System.out.println(lst1); // [[5]]
List<List<Integer>> lstShallowCopy = new ArrayList<>(lst1); // shallow copy
List<List<Integer>> lstDeepCopy = lst1.stream()
   .map(ArrayList::new)
   .collect(toList()); // deep copy
List<List<Integer>> lstNotACopy = lst1; // not a copy at all

lst1.get(0).add(6);
lst1.add(Arrays.asList(7));

System.out.println(lst1); // [[5, 6], [7]]
System.out.println(lstShallowCopy); 
  // [[5, 6]]: shows modifications to the original elements, but 
  // doesn't include new elements
System.out.println(lstDeepCopy); // [[5]]
  // shows no modifications at all
System.out.println(lstNotACopy); // [[5, 6], [7]]
  // shows all modifications

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=20794&siteId=1