Java深度复制-错误的引用分配 请考虑以下代码 public class Pair implements Cloneable, Comparable<Para> { ... public Pair(String key, double value) throws Exception { if (value <= 0) throw new IllegalArgumentException(); this.key = key; this.value = value; } ... @Override public Pair clone() throws CloneNotSupportedException { return (Pair) super.clone(); } }
我假设没有正确设置对树Java深度复制-错误的引用分配 请考虑以下代码 public class Pair implements Cloneable, Comparable<Para> { ... public Pair(String key, double value) throws Exception { if (value <= 0) throw new IllegalArgumentException(); this.key = key; this.value = value; } ... @Override public Pair clone() throws CloneNotSupportedException { return (Pair) super.clone(); } },java,interface,clone,cloneable,Java,Interface,Clone,Cloneable,我假设没有正确设置对树alfa和beta的引用。我为什么这么认为?请看下面的内容 alfa.printTree(); //(VOID 1,00), (a 1,00), (b 2,00), (c 3,00), (e 5,00) beta.printTree(); //(VOID 1,00), (a 1,00), (b 2,00), (c 3,00), (e 5,00) beta.remove("a"); alfa.printTree(); //(VOID 1,00), (
alfa
和beta
的引用。我为什么这么认为?请看下面的内容
alfa.printTree(); //(VOID 1,00), (a 1,00), (b 2,00), (c 3,00), (e 5,00)
beta.printTree(); //(VOID 1,00), (a 1,00), (b 2,00), (c 3,00), (e 5,00)
beta.remove("a");
alfa.printTree(); //(VOID 1,00), (b 2,00), (c 3,00), (e 5,00)
beta.printTree(); //(VOID 1,00), (a 1,00), (b 2,00), (c 3,00), (e 5,00)
alfa.remove("e");
alfa.printTree(); //(VOID 1,00), (b 2,00), (c 3,00), (e 5,00)
beta.printTree(); //(VOID 1,00), (a 1,00), (b 2,00), (c 3,00), (e 5,00)
因此,您可以看到,克隆后,从beta
中删除任何内容实际上都会从alfa
中删除,而从alfa
中删除则根本不会删除。当然,在调用clone()
之前,alfa
上的每个操作都正常工作
这是为了学习,主要任务是实现一个有效的clone()
方法,因此我不想使用任何其他方法来执行深度复制
请告知我做错了什么,因为自调试还没有起到帮助作用。父级更新似乎缺失--不确定这是否是唯一的问题
@Override
public Node clone() throws CloneNotSupportedException {
Node cloned = new Node();
cloned.elem = elem.clone();
if (left != null) {
cloned.left = left.clone();
cloned.left.parent = cloned;
}
if (right != null) {
cloned.right = right.clone();
cloned.right.parent = cloned;
}
return cloned;
}
另外,我认为另一个问题是节点是一个非静态的内部类。因此,它总是有一个隐式指针指向它在中创建的树。在Node.clone中调用new Node()时,它位于原始树的作用域内,因此它仍将指向原始树,但它需要是新树的内部类。向内部类声明添加static将突出显示问题
您可能希望将其转换为静态内部类,并添加指向树的显式指针(如果需要的话——一些访问根的节点方法看起来应该是BSTtree方法)。没错,我忘了更新父节点。尽管如此,主要问题仍然存在,因此我的代码存在更多问题。BSTTree的成员是否比root多?我认为错误可能不在你发布的片段中……是的,它确实存在。这是BSTtree类和Pair类的完整代码,我在BSTtree中没有找到任何其他字段,但是一些节点方法似乎可以访问外部类的字段根。并且不能在clone()中调整外部类--节点将保留其所有者的根引用。我将把Node转换成一个静态的内部类,并修复其影响。所有的节点都有一个对bstrre的隐式引用,因为它们是非静态的内部类。在Node.clone中调用new Node()时,这在原始树的范围内,因此它们仍将指向原始树,但需要指向新树。向内部类声明中添加static将突出显示问题。如果不调用
Object.clone()
,则实现Cloneable
是毫无意义的。
alfa.printTree(); //(VOID 1,00), (a 1,00), (b 2,00), (c 3,00), (e 5,00)
beta.printTree(); //(VOID 1,00), (a 1,00), (b 2,00), (c 3,00), (e 5,00)
beta.remove("a");
alfa.printTree(); //(VOID 1,00), (b 2,00), (c 3,00), (e 5,00)
beta.printTree(); //(VOID 1,00), (a 1,00), (b 2,00), (c 3,00), (e 5,00)
alfa.remove("e");
alfa.printTree(); //(VOID 1,00), (b 2,00), (c 3,00), (e 5,00)
beta.printTree(); //(VOID 1,00), (a 1,00), (b 2,00), (c 3,00), (e 5,00)
@Override
public Node clone() throws CloneNotSupportedException {
Node cloned = new Node();
cloned.elem = elem.clone();
if (left != null) {
cloned.left = left.clone();
cloned.left.parent = cloned;
}
if (right != null) {
cloned.right = right.clone();
cloned.right.parent = cloned;
}
return cloned;
}