cópia superficial do LinkedList não reflete as alterações ao adicionar um novo nó

Peter Nguyen:

diagramaEu fiz um monte de leituras, mas parece que eu não posso limpar a minha confusão sem pedir aqui. Com base no diagrama, quando crio aa cópia superficial de um clone ListaLigada usando (). Um novo LinkedList é criado e o valor de referência da variável de cabeça no original é copiado para o clone do eo resto dos nós são compartilhados. Então, se eu adicionar um novo nó usando o clone, isso deve ser visível para o original não é? Mas quando a impressão list1 o valor 3 é omitido. Alguém pode me dizer o porquê?

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

clone()cria nova LinkedListestrutura e retorna novo referência ao primeiro nó. Relação entre estes dois LinkedLists é que eles compartilham mesmo nó values. Quando você fazer algumas add\ removeoperações na lista de velho ou novo estas operações não vai mudar outra lista. É por isso que nós copy- nós não queremos mudar a estrutura lista ligada original quando mudamos cópia.

De LinkedList.clonedocumentação:

Retorna uma cópia superficial do presente LinkedList. (Os elementos em si não são clonados .) @returnUma cópia superficial deste LinkedListexemplo

Considere exemplo abaixo:

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

impressões código acima:

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

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

Como podemos ver, quando mudamos estado interno do primeiro elemento da primeira lista é visível para segunda lista também. Assim, não há nenhuma cópia profunda de cada valor elemento em vez copiar da estrutura - cópia de nós e ordem.

Para deixar bem claro, vamos dar uma olhada na implementação em 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;
}

Dê uma olhada em for-eachloop. Ele itera sobre lista original e adiciona valores a clonelista. Método addcria novo Nodeobjeto que armazena o mesmo valor que lista original: x.item.

Acho que você gosta

Origin http://43.154.161.224:23101/article/api/json?id=181233&siteId=1
Recomendado
Clasificación