Eu 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);
clone()
cria nova LinkedList
estrutura e retorna novo referência ao primeiro nó. Relação entre estes dois LinkedList
s é que eles compartilham mesmo nó values
. Quando você fazer algumas add
\ remove
operaçõ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.clone
documentação:
Retorna uma cópia superficial do presente
LinkedList
. (Os elementos em si não são clonados .)@return
Uma cópia superficial desteLinkedList
exemplo
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-each
loop. Ele itera sobre lista original e adiciona valores a clone
lista. Método add
cria novo Node
objeto que armazena o mesmo valor que lista original: x.item
.