equals und hashCode Vertrag
Der Vertrag: wenn a.equals(b), dann müssen a.hashCode() und b.hashCode() gleich sein. equals muss reflexiv, symmetrisch und transitiv sein.
HashSet und HashMap nutzen hashCode für die Bucketwahl und equals für die Feinheit. Verletzungen führen zu "verlorenen" Elementen.
Praxis: alle Felder, die equals nutzt, gehören auch in hashCode. mutable Felder als Schlüssel meiden.
Vertrag in der JDK-API: Object.equals [1].
Wo gebraucht
Ohne korrekten Vertrag brechen HashMap/HashSet, ORM-Entitäten in Sets und Deduplizierung in Pipelines. Jede Domänenklasse, die als Map-Key dient (UserId, Coordinate, Money), braucht beide Methoden konsistent.
Vertiefung
Fachliche Gleichheit wird durch equals modelliert. Sie muss reflexiv, symmetrisch, transitiv und über unveränderte Zustände konsistent sein. Der Hashwert verdichtet dieselben relevanten Eigenschaften für eine schnelle Vorauswahl.
Wenn zwei Objekte fachlich gleich sind, müssen sie im selben Hashbereich landen. Die Umkehrung gilt nicht, weil verschiedene Objekte kollidieren dürfen. Deshalb folgt nach der Hashprüfung immer noch eine Gleichheitsprüfung.
Vererbung erschwert symmetrische Gleichheit, wenn eine Unterklasse zusätzliche relevante Felder besitzt. Unveränderliche Wertobjekte oder Komposition liefern häufig einen klareren Vertrag als eine erweiterbare Gleichheitshierarchie.
Schwierigkeitsstufen
- Die Eigenschaften einer Äquivalenzrelation prüfen.
- Zulässige Kollisionen von Vertragsverletzungen unterscheiden.
- Gleichheit in einer Vererbungshierarchie beurteilen.
Fallstricke
Nur eine der beiden Methoden zu überschreiben beschädigt hashbasierte Sammlungen. Veränderliche Gleichheitsfelder machen bereits eingefügte Schlüssel ebenfalls unzuverlässig.
Sources
Tasks
Card Info
- Topic: Algorithmen und Datenstrukturen
- Difficulty: Intermediate
- Completed: 0 users