为什么我的链表在克隆后似乎指向相同的东西?

时间:2011-09-26 10:02:22

标签: java clone

当我第一次看到

时,我注意到了
list2 = (LinkedList)list.clone();

我可以独立操作两个列表,例如。 list2.remove(1)

但是后来我做的时候

list = (LinkedList)list2.clone();

当我list.remove(1)时,list2也会受到影响。那是为什么?

更新

我的代码http://pastie.org/2598096

示例输入:

4 8
1 5 2 3
4
I 1 2
R 2
C 1 10
I 4 2

> javac Main.java && java Main < ./input/betterlist0.in 
[ 1, 5, 2, 3, ] -- [ 2, 1, 5, 2, 3, ] // list2 can be modified from list1 independently
YES9 8
[ 2, 5, 2, 3, ] -- [ 2, 5, 2, 3, ] // now when list2 is modified, list1 gets modified too. 

我认为它是因为super.clone()制作了浅层副本。但为什么它第一次运作呢?

4 个答案:

答案 0 :(得分:3)

通常,您应该编写自己的clone()函数来实现所需的深层复制。因为java不保证这一点。

以下是wikipedia的引用:

  

Object.clone()的默认实现执行浅拷贝。当一个类需要深拷贝或其他一些自定义行为时,他们必须在从超类中获取副本后在他们自己的clone()方法中执行它。

我认为this也值得一读。

答案 1 :(得分:3)

LinkedList l1 = new LinkedList();
l1.add("A");l1.add("B");

LinkedList l2 = (LinkedList)l1.clone();
out("l2 after clone: "+l2.size());
l2.remove(0);
out("l2 after remove: "+l2.size());
l1 = (LinkedList)l2.clone();
out("l1 cloned from l2: "+l1.size());
l1.remove(0);
out("l1 after remove :"+l1.size());
out("l2 after l1's remove:"+l2.size());

使:

l2 after clone: 2
l2 after remove: 1
l1 cloned from l2: 1
l1 after remove :0
l2 after l1's remove:1

演示

  

.clone

按预期工作。

答案 2 :(得分:0)

  

当我做list.remove(1)list2也受影响

不,不是。你的意见在这里是错误的。

答案 3 :(得分:0)

这也是可能发生的事情。

基本上,列表可能不包含实际的对象数据,而是对它们的引用。换句话说,它跟踪那些对象的指针(a.k.a.内存地址)。

在英语中,这就像是说“这些房子在这些地址”,并且您将地址列表存储在电话簿中。 clone()可能没有复制房子,但可能是复制电话簿

也有可能有人存储“电话簿存放在架子B上”,将其写下来,并向其他人发送一张纸,上面写着“电话簿存放在架子B上”