gpt4 book ai didi

java - 在同一个类中克隆函数

转载 作者:行者123 更新时间:2023-12-02 04:11:51 26 4
gpt4 key购买 nike

我正在用java进行一些模拟。我试图提前几步模拟树的节点,然后丢弃所有更改并返回到原始状态。但克隆()没有返回正确的结果。

节点类:

public class TreeNode implements Serializable,Cloneable{

HashMap<Integer, Tracker> trackers;

public Object clone(){
try{
TreeNode node = (TreeNode) super.clone();
HashMap<Integer, Tracker> newTrackers = new HashMap<Integer, Tracker>;
for (int i=0:i<4:i++){
newTrackers.put(i, node.trackers.get(i).clone());
}
node.trackers = newTrackers;
return node;
}catch(CloneNotSupportException e){
}
return null;
}

public run(){

TreeNode current = root;
TreeNode CopyNode = (TreeNode) current.clone();
foo(CopyNode);

//Here both current and CopyNode have the same changes at trackers
//made by foo()
}

}

跟踪器类:

public class Tracker implements Serializable,Cloneable{
private final Player player;

public Tracker clone(){
try{
Tracker newTracker = (Tracker) super.clone();
newTracker.player = player.clone();
return newTracker;
} catch (CloneNotSupportException e){
}
return null;
}

玩家等级:

public class Player implements Serializable,Cloneable{
private int points;

public Player clone(){
try{
return (Player) super.clone();
}catch (CloneNotSupportException e){
}
return null;
}
}

注意:我不能使用 apache 函数,例如 org.apache.commons.lang.SerializationUtils

最佳答案

将克隆方法更改为:

public TreeNode clone(){
try {
TreeNode node = (TreeNode) super.clone();
node.trackers = (HashMap<Integer, SomeOtherClass>) trackers.clone();
return node;
} catch (CloneNotSupportedException e) {
return null;
}
}

之前,TreeNode 的两个副本都引用了相同的跟踪器 HashMap,因此更改一个副本也会更改另一个副本。然而,通过显式地创建跟踪器的新副本,两个节点现在拥有 HashMap 的两个副本,因此更改一个节点不会影响另一个节点。

这是假设 HashMap 中包含的对象没有被更改。如果是,这些更改将反射(reflect)在两个副本中。

有关Java中复制的更详细说明,请参阅How do I copy an object in Java?的第二个答案

-- 编辑--

如果跟踪器中的现有元素被 foo 修改,您也需要复制每个元素。目前,您有 HashMap 的两个副本,但每个副本都有指向同一对象的引用。因此,编辑一个 HashMap 中的对象会更改另一个 HashMap 中的该对象。你可以这样做:

public TreeNode clone(){
try {
TreeNode node = (TreeNode) super.clone();
HashMap<Integer, SomeOtherClass> newTrackers = new HashMap<>();
for (Integer key : trackers.keySet()) {
newTrackers.put(key, trackers.get(key).clone());
}
node.trackers = newTrackers;
return node;
} catch (CloneNotSupportedException e) {
return null;
}
}

但是,这依赖于跟踪器中 SomeOtherClass 的对象本身具有正确实现的克隆方法这一事实。否则,您最终会遇到同样的问题,它们引用的任何对象都将与原始 HashMap 中的对象相同。不幸的是,在 Java 中,如果不为所有使用的对象显式编码,似乎没有简单的方法来创建深度克隆。

-- 编辑 2--

将您的 Tracker 克隆更改为:

public Tracker clone() {
try {
Tracker newTracker = (Tracker) super.clone();
newTracker.player = player.clone();
return newTracker;
} catch (CloneNotSupportException e){
}
return null;
}

只要一个对象引用了另一个对象,您就需要克隆它们。由于 Player 没有对对象的引用,只有原始类型,因此现在应该可以正常工作。

关于java - 在同一个类中克隆函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33713880/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com