自定义链接列表的深克隆



我正在尝试实现克隆方法,以深层克隆自定义链接列表(矩形对象)。当列表中没有元素或单个元素时,我能够获得正确的值,而当列表中有一个以上的元素时,我可以获得正确的值。我认为问题是在mylinknode类中使用我的克隆方法。有人可以帮我吗?

注意:我已经缩短了用于可读性目的的代码

class Rectangle implements Cloneable {
    private double width;
    private double height;
    // setters and getters for these class variables
    public Object clone() {
        try {
            Object rectClone = super.clone();
            return (Rectangle) rectClone;
        } catch (CloneNotSupportedException c) {
            return null;
        }
    }
}

public class MyList implements Cloneable {
    private MyListNode head;
    public Object clone() {
        try {
            Object listClone = super.clone();
            if (head != null) {
                ((MyList) listClone).head = (MyListNode) head.clone();
            }
            return (MyList) listClone;
        } catch (CloneNotSupportedException c) {
            return null;
        }
    }
}

class MyListNode implements Cloneable {
    private Rectangle rectangle;
    private MyListNode next;
    // getter setter for class properties
    protected MyListNode clone() {
        try {
            Object NodeClone = super.clone();
            ((MyListNode) NodeClone).rectangle = (Rectangle) rectangle.clone();
            MyListNode temp = this.next;
            while (temp != null) {
                ((MyListNode) NodeClone).rectangle = (Rectangle) rectangle
                        .clone();
                temp = temp.getNext();
                //edited later, posted by mistake
                //clone();
            }
            return (MyListNode) NodeClone;
        } catch (CloneNotSupportedException c) {
            return null;
        }
    }
}

---我使用递归的克隆方法(另一种尝试) -

protected MyListNode clone() {
    try {
        Object nodeClone = super.clone();
        MyListNode temp = this.next;
        if( temp == null){
        ((MyListNode) nodeClone).rectangle = (Rectangle)this.rectangle.clone();
        ((MyListNode) nodeClone).next = this.next.clone();
        temp = temp.getNext();
        }
        else{
            clone();
        }
        return  (MyListNode)nodeClone;      

    }catch (CloneNotSupportedException c) {
        return null;
    }

}

- 尽管结果似乎是正确的(对以前的方法的校正),但这个似乎对整个事情都有效 -

protected MyListNode clone() {
    try {
        Object listNodeCopy = super.clone();
        MyListNode temp = this.next;
        if (temp == null) {
            ((MyListNode) nodeClone).rectangle = (Rectangle) this.rectangle.clone();
        } else {
            while (temp != null) {
                ((MyListNode) nodeClone).rectangle = (Rectangle) this.rectangle.clone();
                ((MyListNode) nodeClone).next = temp.clone();
                temp = temp.getNext();
            }
        }
    return (MyListNode) listNodeCopy;
    } catch (CloneNotSupportedException c) {
        return null;
    }
}

对此的任何帮助将不胜感激!我是克隆和自定义链接列表的新手,并且已经尝试这样做很长时间了:(

您的迭代方法是错误的。您必须克隆每个节点,因此必须在列表类中进行。如果您尝试在第一个节点上克隆剩余的节点时将其克隆在第一个节点上,则将其余的节点递归克隆。因此,第一个节点将被克隆一次,第二个节点两次,第三次,等等。

我将尝试修复您的递归方法。

    if( temp == null){ // <-- temp is null!! should be != null
        ((MyListNode) nodeClone).rectangle = (Employee)this.rectangle.clone(); <-- Employee ?!?!
        ((MyListNode) nodeClone).next = this.next.clone();
        temp = temp.getNext(); <-- This throws NPE as temp is null!! But it is useless anyway. Remove this line.
    }

这确实有效:

protected MyListNode clone() {
    try {
        Object nodeClone = super.clone();
        ((MyListNode) nodeClone).rectangle = (Rectangle) this.rectangle.clone();
        if (this.next != null) {
            ((MyListNode) nodeClone).next = this.next.clone();
        }
        return (MyListNode) nodeClone;
    } catch (CloneNotSupportedException c) {
        throw new RuntimeException(c); // <<- This is the best for impossible conditions so if they happen you notice
    }
}

,所以这是我的方法。我认为它可以正常工作,但有人可以确认吗?

Object nodeClone = super.clone();
        MyListNode temp = this.next;
        if(temp == null){
            ((MyListNode) nodeClone).rectangle = (Employee) this.rectangle.clone();
            return (MyListNode)nodeClone;
        }else{
            while(temp != null){
                ((MyListNode) nodeClone).rectangle = (Rectangle) this.rectangle.clone();
                ((MyListNode) nodeClone).next = this.next.clone();
                temp = temp.getNext();
                return (MyListNode) nodeClone;

最新更新