Java中对象的深层克隆

时间:2016-11-27 16:58:30

标签: java list clone

嗨大家我有以下课程

public class Person{
    private Person parent;
    private int position;
    private List<Person> siblings;

    public Person(Person person) {
        if (this.parent != null) {
            this.parent = new Person(person.parent);
        } else {
            this.parent = null;
        }
        this.position = person.position;
        //this.siblings = person.siblings;
        this.siblings = cloneList(person.siblings);
    }
    // End Constructor

    // Start Methods and Functions
    public static List<Person> cloneList(List<Person> persons) {
        List<Person> clonedList = new ArrayList<Person>(persons.size());
        if (persons != null) {
            for (Person person : persons) {
                clonedList.add(new Person(person));
            }
        }
        return clonedList;
    }
    // End Methods and Functions
}

由于人与人之间存在很多关系,在我的情况下,兄弟姐妹也可以是父母,反之亦然,我最终会遇到StackOverflowError。

我正在创建几百个对象,这些对象彼此存在某种关系,这些对象存储在兄弟列表和父变量中。然后在处理时我需要复制整个状态并将该状态存储在列表中并继续处理第一个状态而不影响克隆状态,当需要再次出现时,我需要创建该状态的另一个克隆并将其添加到同一个清单。当我完成处理第一个状态时,我希望获得列表中的下一个状态(在处理第一个列表时已经创建)并处理这个状态。同样会有一些状态需要克隆并添加到列表中,直到当前状态完成并进入下一个状态,直到所有状态都被处理完毕。

我已经在stackoverflow和其他地方阅读了很多建议,但似乎没有一个完全适合我想要的。

似乎我在构造函数和cloneList方法的无限递归状态下结束。

我遇到过Java中的Cloneable Interface但是已经阅读过这不是最好用的。

关于如何解决这个问题的任何想法,或者你可以指导我获得我需要的信息,我们将非常感激。

感谢。

编辑:粘贴和编辑代码时出错。 改变了:     this.parent = new Person(Person.parent); 至     this.parent = new Person(person.parent);

因为它应该从传递给构造函数的对象的引用创建一个新的Person。

1 个答案:

答案 0 :(得分:1)

我发现如果你有一个非常复杂的对象与其他对象有多个引用,那么克隆该对象非常困难。 Java <script src="https://cdnjs.cloudflare.com/ajax/libs/xregexp/3.1.1/xregexp-all.js"></script>方法不会非常优雅地支持你。我会做什么,使对象序列化,然后反序列化。这将为您提供该对象的完美克隆。

clone

您标记对象class Person implements Serializable{ // YOUR CODE GOES HERE........... public Person makeClone() throws IOException, ClassNotFoundException { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(outputStream); out.writeObject(this); ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); ObjectInputStream in = new ObjectInputStream(inputStream); Person copied = (Person) in.readObject(); return copied; } ,然后将其写入Serializable。然后ByteArrayOutputStream。这将确保您将获得与州完全不同的对象。研究java Serializable。因为有某种方法可以序列化对象。