2 Stimmen

Zusammengesetzter String-Schlüssel in HashMap

Wir speichern einen String-Schlüssel in einer HashMap, die eine Verkettung von drei String-Feldern und einem booleschen Feld ist. Das Problem ist, dass doppelte Schlüssel erstellt werden können, wenn das Trennzeichen im Feldwert erscheint.

Um dies zu umgehen, wurde auf der Grundlage der Ratschläge in eine andere Post, ich plane, eine Schlüsselklasse zu erstellen, die als HashMap-Schlüssel verwendet werden soll:

class TheKey {
  public final String k1;
  public final String k2;
  public final String k3;
  public final boolean k4;

  public TheKey(String k1, String k2, String k3, boolean k4) {
    this.k1 = k1; this.k2 = k2; this.k3 = k3; this.k4 = k4;
  }

  public boolean equals(Object o) {
      TheKey other = (TheKey) o;
      //return true if all four fields are equal
  }

  public int hashCode() {
    return ???;  
  }
}

Meine Fragen sind:

  1. Welcher Wert von hashCode() zurückgegeben werden soll. Die Map wird insgesamt etwa 30 Werte enthalten. Von diesen 30 gibt es etwa 10 verschiedene Werte von k1 (einige Einträge haben denselben k1-Wert).
  2. Um diese Schlüsselklasse als HashMap-Schlüssel zu speichern, muss man nur die Methoden equals() und hashCode() überschreiben? Ist noch etwas anderes erforderlich?

1voto

Paul Lammertsma Punkte 36529

Haben Sie einen Blick auf die Spezifikationen von hashCode() ? Vielleicht gibt Ihnen das eine bessere Vorstellung davon, was die Funktion zurückgeben sollte.

1voto

Wolfgang Punkte 3460

Ich weiß nicht, ob dies eine Option für Sie ist, aber die Apache-Commons-Bibliothek bietet eine Implementierung für MultiKeyMap

1voto

Steven Schlansker Punkte 35955

Für den HashCode könnte man stattdessen so etwas verwenden wie

k1.hashCode() ^ k2.hashCode() ^ k3.hashCode() ^ k4.hashCode()

XOR ist entropieerhaltend, und dies integriert k4's hashCode auf eine viel bessere Weise als die vorherigen Vorschläge. Nur ein Bit der Information von k4 bedeutet, dass, wenn alle Ihre zusammengesetzten Schlüssel identische k1, k2, k3 und nur unterschiedliche k4s haben, Ihre HashCodes alle identisch sein werden und Sie eine degenerierte HashMap erhalten werden.

1voto

Adriaan Koster Punkte 15224

Ich dachte, Ihr Hauptanliegen sei die Geschwindigkeit (ausgehend von Ihrem ursprünglichen Beitrag)? Warum stellen Sie nicht einfach sicher, dass Sie ein Trennzeichen verwenden, das in Ihren (einer Handvoll) Feldwerten nicht vorkommt? Dann können Sie einfach einen String-Schlüssel mit Hilfe der Verkettung erstellen und sich diesen ganzen "Schlüsselklassen"-Hokuspokus sparen. Das riecht für mich nach ernsthaftem Over-Engineering.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X