Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

diagram 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); 
like image 789
Peter Nguyen Avatar asked Mar 09 '19 18:03

Peter Nguyen


People also ask

What is a shallow copy of a linked list?

A linkedlist is just a class with one field which is a ref to a head node. Each node is an individual object which contains a ref to its next. Like you said, a shallow copy doesn't copy the node. So when i add a new node, the current last node's next variable refers to the next node.

What is the difference between shallow copy and deepcopy in Java?

In Shallow copy, a copy of the original object is stored and only the reference address is finally copied. In Deep copy, the copy of the original object and the repetitive copies both are stored.

How do I find the next node in a linked list?

LinkedList implements the Collection (and List) interface, so given an index i of an element in the list list , you can get previous and next elements with list. get(i-1) and list. get(i+1) , respectively.

Is copy constructor deep or shallow copy?

Deep copy is performed by implementing our own copy constructor.


1 Answers

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.

like image 158
Michał Ziober Avatar answered Sep 23 '22 03:09

Michał Ziober