2015-06-22 4 views
7

Ich arbeite gerade an einer Graphen-Bibliothek für Java. Wie Sie erwarten, gibt es eine Vertex Klasse. Diese Klasse enthält ein Objekt vom Typ VertexData<T> und kann selbst alles enthalten.
(Ich weiß, das könnte redundant sein und ich könnte einfach Vertex<T> tun, aber für den Zweck der Frage ist es egal).
Ich habe VertexData<T>Cloneable implementieren und eine public VertexData<T> clone() Methode haben eine tiefe Kopie von Serialisierung und Deserialisierung die anruf Object, ziemlich genau wie beschrieben Rückkehr hereWird seichte Kopie wirklich benötigt?

Nun ist die Frage, da ich eine Methode tiefe Kopie zu tun haben, macht es Sinn, auch eine flache Kopie zu haben? Wenn ja, was wäre ein Fall, in dem eine flache Kopie gegenüber einer tiefen Kopie vorzuziehen wäre?

UPDATE: Da die meisten der Antworten und Kommentare einige Erklärungen enthalten, was eine oberflächliche Kopie in der einen oder anderen Weise ist, fühle ich mich so, dass ich ein wenig verdeutlichen muss. Ich weiß, was eine flache Kopie ist, wie es funktioniert, alles. Meine Frage ist, dass, da es eine Bibliothek ist, die ich entwickle, und da ich eine tiefe Kopiermethode erstellt habe, macht es Sinn, auch eine Methode für flache Kopie zur Verfügung zu stellen?

Ich werde auch hier hinzufügen, dass es keine primitiven Typen in VertexData<T> Klasse enthalten sind.
Also im Kontext einer Container-Klasse zum Speichern von Vertex-Daten für ein Diagramm Bibliothek, wird eine flache Kopie jemals benötigt werden?
Wenn ja, können Sie sich ein Beispiel vorstellen, im Kontext dessen, was ich entwickle?
Wenn nicht sollte ich eine seichte Kopiermethode nur der Vollständigkeit halber hinzufügen?
Ist das eine gute Übung oder spielt es keine Rolle?

+4

Flache Kopien sind nützlich, wenn Sie Kopien von Klassen erstellen möchten, die eine große zugrunde liegende Datenstruktur oder einen Datensatz gemeinsam haben.Wenn Sie zum Beispiel mehrere "Client" -Klassen haben, die alle einen Verweis auf eine große Datenstrukturreferenz haben, würde eine tiefe Kopie versuchen, eine Kopie der zugrunde liegenden Daten zu erstellen, wenn Sie eine Kopie des Clients erstellen möchten , was nicht unbedingt das ist, was du willst. –

+0

Es ist situationsbedingt. Flaches Kopieren bedeutet im Allgemeinen, dass nur eine Ebene eines Objekts kopiert wird, während tiefes Kopieren im Allgemeinen bedeutet, dass alles auf mehreren Ebenen kopiert wird. – Adam

+0

Normalerweise erstellen Sie flache Kopien, wenn Sie unveränderliche Objekte referenzieren, aber das ist nur ein Beispiel, keine Regel. – biziclop

Antwort

1

Behälterartiges wie List<Point> in einigen Fällen kann eine Gruppe von X halten zu verwendet werden, Y-Koordinatenpaaren, aber in anderen Fällen zu verwendet werden kann ein Bündel von beweglichen Punkten identifizieren, die durch anderen Code verwendet werden, . Der erstgenannte Fall kann in Unterfälle unterteilt werden, wo der Besitzer des List<Point> auch der ausschließliche Eigentümer der Point Instanzen darin ist und diese nach Belieben modifizieren kann, oder wo der Eigentümer diese Instanzen niemals modifizieren wird, aber Verweise auf sie mit Code teilen kann, der verspricht um sie auch nicht zu modifizieren.

Wenn die List<Point> verwendet wird zum Einkapseln (X, Y) Koordinatenpaaren, aber die der Besitzer könnte die Point Gegenstände darin gehalten modifizieren, dann eine korrekte Klon des List<Point> müssen Verweise auf Kopien der Point betreffenden Objekte halten. Wenn es Koordinatenpaare kapselt, aber niemand jemals die Objekte darin verändern wird (und Empfänger einer geklonten Liste keine Referenzen auf die darin enthaltenen Objekte für irgendeinen Code verfügbar machen würden, der sie modifizieren könnte), könnte ein korrekter Klon des List<Point> Referenzen auf beide enthalten die ursprünglichen Point Objekte oder Kopien davon; ersteres wäre schneller, aber letzteres wäre immer noch semantisch korrekt.

Wenn die List<Point>-dient identifizierenPoint Instanzen, die von anderem Code geändert werden können, und eine solche Änderung muss in den List<Point> reflektiert wird selbst dann ein richtiger Klon muss Verweise auf die gleichen Point Objekte hält, wie die ursprüngliche Liste. Wenn ein Klon stattdessen Kopien dieser Point Objekte halten sollte, würde er nicht länger dieselben semantischen Informationen wie die ursprüngliche Liste enthalten. Wenn getrennte Erfassungstypen basierend darauf haben, ob sie Werte mit ausschließlich im Besitz befindlichen veränderbaren Instanzen oder unveränderbaren Instanzen enthalten oder ob sie dazu dienen, die darin enthaltenen Objekte zu identifizieren, wäre ein einziges Konzept des "Klonens" möglich , anstatt "tiefes" und "oberflächliches" Klonen zu erfordern. Ohne eine solche Unterscheidung zwischen den Sammlungsarten ist es jedoch notwendig, Klonierungsmethoden zu haben, die alles tun können, was auf der Grundlage der Dinge in der Sammlung benötigt wird.

0

Sie werden keine flache Kopie benötigen. Eine flache Kopie weist Ihrem bereits vorhandenen Objekt im Speicher eine neue Referenzvariable zu. Ein '=' Operator wird die Arbeit erledigen. Für weitere Details, gehen Sie bitte durch diesen Beitrag - In Java, what is a shallow copy?

+1

Ehm. Ich weiß, was eine flache Kopie ist. Meine Frage war eher so, da ich gerade an einer Bibliothek arbeite, wenn es sinnvoll ist, auch eine flache Kopie zu haben. Wird dieses Ding jemals benötigt, wenn eine tiefe Kopie verfügbar ist? – qbit

+3

Ich stimme nicht zu ... Ob eine seichte Kopie oder eine tiefe Kopie notwendig ist, sollte nicht dem Bibliotheksimplementierer überlassen werden, es sollte dem Benutzer der Bibliothek überlassen werden. Die Bereitstellung beider Methoden würde sicherstellen, dass Ihre Bibliothek in allen Situationen flexibel ist. Dies beantwortet die Frage nicht wirklich. –

+0

Nein. Wer auch immer Ihre Bibliothek benutzt, benutzt den Operator '=', um das zu tun. Sie müssen das nicht bereitstellen. Eine seichte Kopie wird nur dann bevorzugt, wenn jemand eine neue Referenzvariable für einen Speicher benötigt. Wenn Sie möchten, können Sie jedoch eine neue Methode namens public ClassName shallowCopy() {return new ClassName(); // mehr stuff;} wenn Sie noch mehr Sachen mit seichten Kopien machen wollen, aber Sie können Benutzer Ihrer Bibliothek nicht auf den Operator '=' beschränken. –

3

Es kommt wirklich auf die Anforderungen. Wenn Sie wissen, dass Ihr Objekt mehr als nur primitive Felder hat, sollte es (und zum Glück) eine deep copy haben. Es gibt keine "feste Regel" mit shallow oder deep. Da es "auf der Anforderung basiert", wäre es sicher, beides wie @RyanJ in einem Kommentar zu einer anderen Antwort anzugeben.

Wenn Sie Ihre Sammlung oder Ihr Objekt flach kopieren und eine Änderung an einem Attribut vornehmen möchten, werden sowohl die Referenz als auch das kopierte Objekt geändert. Auf der anderen Seite, wenn Sie tief kopieren und in der Lage sein möchten, die Werte eines Objekts oder der Kopie des Objekts zu ändern und NICHT die Kopie und das Original betreffen, ist eine tiefe Kopie alles was Sie brauchen. Alles hängt von der Anforderung ab und was Sie für Ihr Objekt/System benötigen. Meine letzte Empfehlung ist, beides zu tun.

0

Ja, es ist in wenigen Fällen erforderlich. Sie können die Anforderung basierend auf den folgenden Punkten ableiten.

Wenn das Objekt nur primitive Felder enthält, sollten Sie eine flache Kopie verwenden.

Wenn das Objekt Verweise auf andere Objekte enthält, sollten Sie basierend auf der Anforderung eine flache Kopie oder eine tiefe Kopie in Betracht ziehen.

Wenn die Referenzen nicht geändert werden, ist keine Tiefenkopie erforderlich. Hier sollten Sie für seichte Kopie gehen.

Wenn die Referenzen geändert werden, wird eine tiefe Kopie bevorzugt.

flache Kopie:

enter image description here

flache Kopie zu unerwünschten Effekten führen kann, wenn die Elemente der Werte von anderer Referenz geändert werden.

tiefere Kopie:

enter image description here

während tiefer Kopie alle Änderungen an den Array-Wert bezieht sich auf in Veränderungen nicht zur Folge hat, um die Array-Daten beziehen.

können Sie auf this link beziehen, um mehr darüber mit Beispielen zu verstehen.