2016-11-27 3 views
-1

Hallo Leute Ich habe die folgende KlasseTief Klon von Object in Java

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 
} 

Da es viele Beziehungen zwischen den Menschen sind, und die Geschwister in meinem Fall können auch Eltern sein und umgekehrt, ich enden mit einem StackOverflowError.

Ich erstelle ein paar hundert Objekte alle mit einer Beziehung zueinander, die in der Geschwisterliste und Elternvariable gespeichert ist. Dann muss ich während der Verarbeitung eine Kopie des gesamten Zustands erstellen und diesen Zustand in einer Liste speichern und mit der Verarbeitung des ersten Zustands fortfahren, ohne den geklonten Zustand zu beeinflussen. Wenn die Notwendigkeit erneut auftritt, muss ich einen weiteren Klon dieses Zustands erstellen und hinzufügen die gleiche Liste. Wenn ich mit der Verarbeitung des ersten Zustands fertig bin, möchte ich den nächsten Zustand in der Liste erhalten (der während der Verarbeitung der ersten Liste erstellt wurde) und diesen verarbeiten. Auch hier wird es Zustände geben, die geklont und zur Liste hinzugefügt werden müssen, bis der aktuelle Zustand abgeschlossen ist, und zum nächsten Zustand übergehen, bis alle Zustände verarbeitet sind.

Ich habe ein paar Vorschläge sowohl auf Stackoverflow und anderswo gelesen, aber keiner scheint genau zu passen, was ich will.

Es scheint, als ob ich mit dem Konstruktor und der cloneList-Methode in einem endlosen rekursiven Zustand enden würde.

Ich bin in Java auf die Cloneable Interface gestoßen, habe aber gelesen, dass das nicht die beste Sache ist zu verwenden.

Irgendwelche Ideen, wie dies gelöst werden kann, oder vielleicht könnten Sie mich zu den Informationen, die ich brauche, würde sehr geschätzt werden.

Danke.

Edit: Hatte einen Fehler beim Einfügen und Bearbeiten des Codes. Geändert: this.parent = neue Person (Person.parent); bis this.parent = neue Person (person.parent);

, da es eine neue Person aus der Referenz des Objekts erstellen sollte, das an den Konstruktor übergeben wird.

+0

Wenn Sie das gleiche tun, aber mit einer Schleife erhalten Sie nicht die Ausnahme –

+0

@nickzoum Doch er würde eine Endlosschleife bekommen. David, das ist im Wesentlichen, was der GC tun muss, wenn er Objekte löscht. Suchen Sie nach GC-Algorithmen. –

+0

Es ist möglicherweise keine gute Möglichkeit, eine Liste von Geschwistern mit jeder Person zu führen. Sie könnten stattdessen eine Liste von Kindern im Elternteil haben, die leichter zu aktualisieren wäre als das Aktualisieren aller Geschwister. – Robert

Antwort

2

Was ich gefunden habe, wenn Sie sehr komplexes Objekt haben, das mehrere Referenzen mit anderen Objekten hat, um einen Klon dieses Objekt sehr schwierig zu machen. Java clone Methode wird Sie nicht sehr elegant unterstützen. Was ich tun würde, mache das Objekt serialisieren und dann deserialisieren. Dadurch erhalten Sie einen perfekten Klon dieses Objekts.

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; 
} 

Sie markieren das Objekt Serializable und dann schreiben, dass in ByteArrayOutputStream. Und dann Deserialize .Dies wird sicherstellen, dass Sie absolut unterschiedliche Objekte mit dem Status erhalten. Recherchiere über Java Serializable. Weil es eine bestimmte Art gibt, Objekte zu serialisieren.

+0

Ja, habe es gemischt, während ich den Post bearbeitet habe. Es sollte this.parent = new Person (person.parent) sein ;. Ich werde in Serializable schauen und Sie wissen lassen. Danke für die Eingabe. – David

+0

@David aktualisiert :) – seal

+0

Das hat wie ein Charme funktioniert. Danke Siegel sehr geschätzt :) – David