Irgendwelche Nachteil bei der Verwendung willkürlicher Objekte als Kartenschlüssel in Java?

StackOverflow https://stackoverflow.com/questions/635014

  •  10-07-2019
  •  | 
  •  

Frage

Ich habe zwei Arten von Objekten in meiner Anwendung, bei denen jedes Objekt einer Art genau ein entsprechendes Objekt der anderen Art hat.

Die offensichtliche Entscheidung, diese Beziehung im Auge zu behalten, ist a Map<type1, type2>, wie ein Hashmap. Aber irgendwie bin ich misstrauisch. Kann ich ein Objekt als Schlüssel in der Karte verwenden, es herumgeben, es auch in einer anderen Sammlung sitzen lassen und seinen Partner jederzeit von der Karte abrufen?

Nachdem ein Objekt erstellt wurde, ist alles, was ich umsetzt, eine Kennung, oder? Also wahrscheinlich kein Problem dort. Was ist, wenn ich den Schlüssel serialisieren und deserialisiere?

Irgendwelche anderen Einschränkungen? Sollte ich etwas anderes verwenden, um die Objektpaare zu korrelieren, wie eine Nummer, die ich selbst erzeugte?

War es hilfreich?

Lösung

  1. Der Schlüssel muss implementiert werden .equals() und .hashCode() korrekt
  2. Der Schlüssel darf nicht in irgendeiner Weise verändert werden, die es ändert .hashCode() Wert, während es als Schlüssel verwendet wird
  3. Idealerweise jedes Objekt, das als Schlüssel in a verwendet wird HashMap sollte unveränderlich sein. Dies würde automatisch sicherstellen, dass 2. immer wahr gehalten wird.
  4. Objekte, die ansonsten GCDs könnten, können bei der Verwendung als Schlüssel und/oder Wert herumgehalten werden.

Andere Tipps

Ich habe zwei Arten von Objekten in meiner Anwendung, bei denen jedes Objekt einer Art genau ein entsprechendes Objekt der anderen Art hat.

Dies klingt wirklich nach einer HAS-A-Beziehung und könnte daher mit einem einfachen Attribut implementiert werden.

Es hängt von der Implementierung der von Ihnen ausgewählten Karte ab:

  • Hashmap Verwendet gleich () und Hash-Code(). Standardmäßig (im Objekt) basieren diese auf der Objektidentität, die in Ordnung funktioniert, es sei denn, Sie serialisieren/deserialisieren. Mit einer ordnungsgemäßen Implementierung von Equals () und HashCode () basierend auf dem Inhalt des Objekts haben Sie keine Probleme, solange Sie es nicht ändern, während es ein Schlüssel in einer Hash -Karte ist.

  • Treemap Verwendet vergleichen mit(). Es gibt keine Standardimplementierung, daher müssen Sie eine bereitstellen. Die gleichen Einschränkungen gelten wie für die Implementierung von HashCode () und Equals () oben.

Sie können eine Standardkarte verwenden, aber Sie werden starke Verweise auf Ihre Objekte in der Karte behalten. Wenn Ihre Objekte in einer anderen Struktur verwiesen werden und Sie die Karte benötigen, um sie miteinander zu verknüpfen, sollten Sie eine schwache Hashmap verwenden.

Und übrigens müssen Sie nicht gleich und hashcode überschreiben, es sei denn, Sie müssen mehrere Fälle eines Objekts als gleichwertig betrachten ...

Kann ich ein Objekt als Schlüssel in der Karte verwenden, es herumgeben, es auch in einer anderen Sammlung sitzen lassen und seinen Partner jederzeit von der Karte abrufen?

Ja, hier überhaupt kein Problem.

Nachdem ein Objekt erstellt wurde, ist alles, was ich umsetzt, eine Kennung, oder? Also wahrscheinlich kein Problem dort. Was ist, wenn ich den Schlüssel serialisieren und deserialisiere?

Das stimmt, Sie geben nur eine Referenz herum - sie zeigen alle auf dasselbe tatsächliche Objekt. Wenn Sie das Objekt serialisieren oder deserialisieren, würde dies ein neues Objekt erstellen. Wenn Ihr Objekt jedoch gleichmäßig und HashCode ordnungsgemäß implementiert wird, sollten Sie dennoch das neue Deserialized -Objekt verwenden können, um Elemente aus der Karte abzurufen.

Irgendwelche anderen Einschränkungen? Sollte ich etwas anderes verwenden, um die Objektpaare zu korrelieren, wie eine Nummer, die ich selbst erzeugte?

Ja, ja, ja, Sie können nichts ändern, was den HashCode des Objekts ändern würde, während sich das Objekt in der Karte befindet.

Jedes Objekt kann ein Kartenschlüssel sein. Das Wichtigste hier ist, dass Sie .Equals () und .hashcode () für alle Objekte überschreiben, die als Kartenschlüssel verwendet werden.

Der Grund, warum Sie dies tun, ist, dass Equals, wenn Sie dies nicht tun, als Objektgleichheit verstanden werden. Die einzige Möglichkeit, "gleiche" Kartenschlüssel zu finden, besteht darin, einen Griff zum ursprünglichen Objekt selbst zu haben.

Sie überschreiben Hashcode, weil es mit Gleichen übereinstimmen muss. Dies ist so, dass Objekte, die Sie als gleiches Hash definiert haben, identisch.

The failure points are the hashcode and equals functions. If they don't produce consistent and proper return values, the Map will behave strangely. Effective Java has a whole section on them and is highly, highly recommended.

You might consider Google Collection's BiMap.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top