clone() 创建新的LinkedList 结构并返回对第一个节点的新引用。这两个LinkedLists 之间的关系是它们共享同一个节点values。当您对旧列表或新列表进行一些add\ remove 操作时,这些操作不会更改其他列表。这就是为什么我们这样做copy - 我们不想在更改副本时更改原始链表结构。
来自LinkedList.clone 文档:
返回此LinkedList 的浅表副本。 (元素本身
没有被克隆。)
@return 这个LinkedList 实例的浅拷贝
考虑下面的例子:
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);
}
}
上面的代码打印:
[100, 200]
[100, 200, 300]
After change internal state of first element
[101, 200]
[101, 200, 300]
正如我们所见,当我们从第一个列表更改第一个元素的内部状态时,第二个列表也可以看到它。因此,没有每个元素值的深层副本,而是结构的副本 - 节点和顺序的副本。
为了清楚起见,让我们看一下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;
}
看看for-each 循环。它遍历原始列表并将值添加到clone 列表。方法 add 创建新的 Node 对象,该对象存储与原始列表相同的值:x.item。