shallow copy of linkedlist does not reflect changes when adding new node

非 Y 不嫁゛ 提交于 2019-12-23 10:17:24

问题


I have done a lot of readings but seems like I can't clear my confusion without asking here. Based on the diagram, when I create a a shallow copy of a linkedlist using clone(). A new linkedlist is created and the reference value of the head variable in the original is copied to the clone's and the rest of the nodes are shared. So if I add a new node using the clone, this should be visible to the orginal is it not? But when printing list1 out the value 3 is omitted. Can someone tell me why?

LinkedList<Integer> list1 = new LinkedList<>();
l1.add(1);
l1.add(2);
LinkedList<Integer> list2 = (LinkedList) l1.clone();
l2.add(3); 

回答1:


clone() creates new LinkedList structure and returns new reference to first node. Relation between these two LinkedLists is they share same node values. When you make some add\ remove operations on old or new list these operations will not change other list. This is why we do copy - we do not want to change original linked list structure when we change copy.

From LinkedList.clone documentation:

Returns a shallow copy of this LinkedList. (The elements themselves are not cloned.) @return a shallow copy of this LinkedList instance

Consider below example:

import java.util.LinkedList;
import java.util.concurrent.atomic.AtomicInteger;

public class LinkedListsApp {

    public static void main(String[] args) throws Exception {
        LinkedList<AtomicInteger> l1 = new LinkedList<>();
        l1.add(new AtomicInteger(100));
        l1.add(new AtomicInteger(200));

        LinkedList<AtomicInteger> l2 = (LinkedList) l1.clone();
        l2.add(new AtomicInteger(300));

        System.out.println(l1);
        System.out.println(l2);

        // change element on first list
        l1.get(0).incrementAndGet();

        System.out.println();
        System.out.println("After change internal state of first element");
        System.out.println(l1);
        System.out.println(l2);
    }
}

Above code prints:

[100, 200]
[100, 200, 300]

After change internal state of first element
[101, 200]
[101, 200, 300]

As we can see, when we change internal state of first element from first list it is visible for second list as well. So, there is no deep copy of each element value rather copy of structure - copy of nodes and order.

To make it absolutely clear, let's take a look on implementation in Java 8:

public Object clone() {
    LinkedList<E> clone = superClone();

    // Put clone into "virgin" state
    clone.first = clone.last = null;
    clone.size = 0;
    clone.modCount = 0;

    // Initialize clone with our elements
    for (Node<E> x = first; x != null; x = x.next)
        clone.add(x.item);

    return clone;
}

Take a look on for-each loop. It iterates over original list and adds values to clone list. Method add creates new Node object which stores the same value as original list: x.item.




回答2:


The clone() method creates an exact copy of the first linked list and then returns it to l2 here. What is does is it creates a new instance and copies all the fields from the original one and then returns it to l2 object. If all we want is a shallow copy we can simply use an assignment operator, in that scenario any changes made to l1 will reflect on l2 as no new object is created but only a copy of the reference is created.



来源:https://stackoverflow.com/questions/55080507/shallow-copy-of-linkedlist-does-not-reflect-changes-when-adding-new-node

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