我已经读了很多书,但是好像不问这里就无法消除我的困惑。基于该图,当我使用clone()创建链表的浅表副本时。创建一个新的链表,并将原始变量中head变量的引用值复制到克隆的变量中,并共享其余节点。因此,如果我使用克隆添加新节点,则原始节点应该可以看到它,不是吗?但是当输出列表1时,将省略值3。有人可以告诉我为什么吗?
LinkedList<Integer> list1 = new LinkedList<>();
l1.add(1);
l1.add(2);
LinkedList<Integer> list2 = (LinkedList) l1.clone();
l2.add(3);
Run Code Online (Sandbox Code Playgroud)
clone()创建新LinkedList结构并返回对第一个节点的新引用。这两个之间的关系LinkedList是它们共享相同的节点values。当您对旧列表或新列表进行一些add操作时remove,这些操作不会更改其他列表。这就是我们这样做的原因copy- 当我们更改副本时,我们不想更改原始链表结构。
来自LinkedList.clone文档:
返回 this 的浅表副本
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);
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码打印:
[100, 200]
[100, 200, 300]
After change internal state of first element
[101, 200]
[101, 200, 300]
Run Code Online (Sandbox Code Playgroud)
正如我们所看到的,当我们更改第一个列表中第一个元素的内部状态时,它对于第二个列表也是可见的。因此,不存在每个元素值的深层复制,而是结构的复制 - 节点和顺序的复制。
为了完全清楚起见,让我们看一下中的实现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;
}
Run Code Online (Sandbox Code Playgroud)
看看for-each循环。它迭代原始列表并将值添加到clone列表中。方法add创建新Node对象,该对象存储与原始列表相同的值:x.item。
| 归档时间: |
|
| 查看次数: |
184 次 |
| 最近记录: |