Java 使用可序列化但仍然获得对象的浅拷贝
我浏览了其他问题,并找到了关于如何对包含引用的对象进行深度复制的解决方案。我特别想做一个树的深拷贝。从逻辑上讲,每个树节点都包含对其子节点的引用。下面是我的节点类的基础知识Java 使用可序列化但仍然获得对象的浅拷贝,java,tree,deep-copy,Java,Tree,Deep Copy,我浏览了其他问题,并找到了关于如何对包含引用的对象进行深度复制的解决方案。我特别想做一个树的深拷贝。从逻辑上讲,每个树节点都包含对其子节点的引用。下面是我的节点类的基础知识 public class BSTNode implements Comparable, Serializable { private String token; private int count; private BSTNode leftChild; private BSTNode ri
public class BSTNode implements Comparable, Serializable {
private String token;
private int count;
private BSTNode leftChild;
private BSTNode rightChild;
我知道我必须只制作一个浅层副本,因为当我制作一个名为tree2的tree1副本并编辑tree1时,编辑也会出现在tree2上。这是我的BSTNode
类中的复制方法
public BSTNode copy()
{
BSTNode obj = null;
try{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bos);
out.writeObject(this);
out.flush();
out.close();
ObjectInputStream in= new ObjectInputStream(new ByteArrayInputStream(
bos.toByteArray()));
obj = (BSTNode) in.readObject();
}
catch(Exception e)
{
e.printStackTrace();
}
return obj;
}
当我希望复制整个树时,我使用下面的方法从我的BSTree
类调用上面的copy方法。(我有两个方法,因为这是一个家庭作业,需要一个调用前序遍历方法的copy方法)
我使用这些行创建新树并将副本分配给它
BSTree tree2 = new BSTree();
tree2.setRoot(tree1.copy());
进一步说,当我对树1进行更改时,树2也会更改。我不知道我做错了什么。我相信这一定是我如何归还这棵新树或其他什么东西。非常感谢您的帮助
编辑
这里是我最初称之为副本的地方。它在自己的类中拥有main方法
setRoot(tree1.copy())
然后,它移动到b树类
,并执行此操作
public BSTNode copy()
{
//BSTNode copiedTreeRoot = new BSTNode();
//return copyTree(copiedTreeRoot,root);
return root.copyTree(root
}
public BSTNode copyTree(BSTNode input)
{
if(input == null)
{
return null;
}
else
{
BSTNode node = new BSTNode();
node.token = input.token;
node.count = input.count;
node.leftChild = copyTree(input.leftChild);
node.rightChild = copyTree(input.rightChild);
System.out.println("node being returned: "+ node.getToken());
return node;
}
BSTree类有一个根的成员元素,称为root
然后它跳转到BSTNode类并执行此操作
public BSTNode copy()
{
//BSTNode copiedTreeRoot = new BSTNode();
//return copyTree(copiedTreeRoot,root);
return root.copyTree(root
}
public BSTNode copyTree(BSTNode input)
{
if(input == null)
{
return null;
}
else
{
BSTNode node = new BSTNode();
node.token = input.token;
node.count = input.count;
node.leftChild = copyTree(input.leftChild);
node.rightChild = copyTree(input.rightChild);
System.out.println("node being returned: "+ node.getToken());
return node;
}
}
当我去打印新树的输出时,我得到一个空白。您忘记在
Serializable
类中定义serialVersionUID
;这可能会导致问题……在BSTNode上的copy
方法中,您写出了节点,但没有写出其子节点,尽管写入了对这些子节点的引用。然后,当您使用copyTree
读取节点时,您会将这些引用返回到您复制的版本中。我承认我不知道serialVersionUID
是什么。我是一个相当新的程序员,我很少使用serializable
这个术语。我应该谷歌一下吗?lol@deanosaur你知道如何明确地复制这些子对象吗?我是否需要在根节点的子节点上递归调用BSTNode中的copy
!我会马上试试。我喜欢这个解决方案。我看到的唯一问题是在编辑我的copyTree
时调用copyTree(otherTreeRoot.getleft())
和mycopyTree
方法写入时需要2个参数。我的另一个应该是什么?或者我应该将方法更改为仅采用BSTNode othertreeot
我编辑了copyTree
方法,只采用一个参数,并将copiedTreeRoot
创建为全局变量。这似乎真的造成了一个问题,因为副本是空白的。我还注意到,您让我将新的复制方法添加到BSTNode
中,但我从未调用过I-gabriel,我编辑了我的代码,我认为这应该适合您。您可以像CopiedTree cp=BST.copyTree(rootNodeInput)一样使用它;我的坏,再次更改了代码,之前错误地引用了类名,想要引用对象节点。如果在getRoot中传递了正确的引用,可以将整个代码粘贴到这里吗
public class BSTNode
{
public String token;
public int count;
public BSTNode leftChild;
public BSTNode rightChild;
public static BSTNode copyTree(BSTNode input){
if(input == null){
return null;
}
else{
BSTNode node = new BSTNode();
node.token = input.token;
node.count = input.count;
node.leftChild = BSTNode.copyTree(input.leftChild);
node.rightChild = BSTNode.copyTree(input.rightChild);
return node;
}
}
public static void main(String args[]){
BSTNode root = new BSTNode();
root.token = "root";
root.count = 1;
BSTNode leftChild = new BSTNode();;
leftChild.token = "left child";
leftChild.count = 2;
root.leftChild = leftChild;
BSTNode copy = copyTree(root);
System.out.println(copy.token);
System.out.println(copy.leftChild.token);
}
}