Ich habe ein 2D-Array von Ganzzahlen. Ich möchte, dass sie in eine HashMap eingefügt werden. Ich möchte jedoch auf die Elemente aus der HashMap zugreifen, die auf dem Array-Index basieren. Etwas wie:
Für A [2] [5], map.get(2,5)
das einen diesem Schlüssel zugeordneten Wert zurückgibt. Aber wie erstelle ich eine HashMap mit einem Schlüsselpaar? Oder im Allgemeinen mehrere Schlüssel: Map<((key1, key2,..,keyN), Value)
so, dass ich mit get (key1, key2, ... keyN) auf das Element zugreifen kann.
EDIT: 3 Jahre nach dem Posten der Frage möchte ich noch ein bisschen mehr hinzufügen
Ich bin auf einen anderen Weg gestoßen NxN matrix
.
Array-Indizes i
und j
können auf key
folgende Weise als einzelne dargestellt werden:
int key = i * N + j;
//map.put(key, a[i][j]); // queue.add(key);
Und die Indizes können auf folgende Weise abgerufen key
werden:
int i = key / N;
int j = key % N;
Antworten:
Es gibt mehrere Möglichkeiten:
2 Dimensionen
Karte der Karten
Wrapper-Schlüsselobjekt
Umsetzung
equals()
undhashCode()
ist hier entscheidend. Dann verwenden Sie einfach:und:
Table
von GuaveTable
verwendet Karte der Karten darunter.N Abmessungen
Beachten Sie das Besondere
Key
Klasse der einzige Ansatz ist, der auf n-Dimensionen skaliert. Sie könnten auch überlegen:Aber das ist aus Sicht der Leistung sowie der Lesbarkeit und Korrektheit schrecklich (keine einfache Möglichkeit, die Listengröße durchzusetzen).
Vielleicht werfen Sie einen Blick auf Scala, wo Sie Tupel und
case
Klassen haben (ganzeKey
Klasse durch Einzeiler ersetzen ).quelle
Map.Entry<K, V>
als Schlüssel verwenden?Map<Pair<Key1, Key2>, Value>
?hashCode()
auch mit einer einzelnen Zeile alsObjects.hash(x,y)
Wenn Sie Ihr eigenes Schlüsselpaarobjekt erstellen, sollten Sie sich einigen Dingen stellen.
Zunächst sollten Sie sich der Implementierung von
hashCode()
und bewusst seinequals()
. Sie müssen dies tun.Zweitens
hashCode()
stellen Sie bei der Implementierung sicher, dass Sie verstehen, wie es funktioniert. Das angegebene Benutzerbeispielist tatsächlich eine der schlechtesten Implementierungen, die Sie tun können. Der Grund ist einfach: Sie haben viele gleiche Hashes! Und die
hashCode()
sollten int-Werte zurückgeben, die eher selten und im besten Fall einzigartig sind. Verwenden Sie so etwas:Dies ist schnell und gibt eindeutige Hashes für Schlüssel zwischen -2 ^ 16 und 2 ^ 16-1 (-65536 bis 65535) zurück. Das passt in fast jedem Fall. Sehr selten sind Sie außerhalb dieser Grenzen.
Drittens sollten Sie bei der Implementierung
equals()
auch wissen, wofür es verwendet wird, und wissen, wie Sie Ihre Schlüssel erstellen, da es sich um Objekte handelt. Oft tun Sie dies unnötig, wenn Anweisungen dazu führen, dass Sie immer das gleiche Ergebnis erzielen.Wenn Sie Schlüssel wie diesen erstellen:
map.put(new Key(x,y),V);
Sie werden niemals die Referenzen Ihrer Schlüssel vergleichen. Denn jedes Mal, wenn Sie auf die Karte zugreifen möchten, werden Sie so etwas tunmap.get(new Key(x,y));
. Daherequals()
braucht man keine Aussage wieif (this == obj)
. Es wird niemals auftreten.Anstatt
if (getClass() != obj.getClass())
in Ihrerequals()
besseren Nutzungif (!(obj instanceof this))
. Es gilt auch für Unterklassen.Das einzige, was Sie vergleichen müssen, ist tatsächlich X und Y. Also das Beste
equals()
Implementierung in diesem Fall wäre also:Am Ende sieht Ihre Schlüsselklasse also so aus:
Sie können Ihre Dimensionsindizes
X
undY
eine öffentliche Zugriffsebene angeben, da diese endgültig sind und keine vertraulichen Informationen enthalten. Ich bin mir nicht 100% sicher, ob dieprivate
Zugriffsebene in irgendeiner korrekt funktioniert beim CastingObject
auf a FallKey
.Wenn Sie sich über das Finale wundern, erkläre ich alles als endgültig, welcher Wert auf Instanzen gesetzt ist und sich nie ändert - und daher eine Objektkonstante ist.
quelle
Sie können keine Hash-Map mit mehreren Schlüsseln haben, aber Sie können ein Objekt haben, das mehrere Parameter als Schlüssel verwendet.
Erstellen Sie ein Objekt namens Index, das einen x- und einen y-Wert annimmt.
Dann müssen Sie
HashMap<Index, Value>
Ihr Ergebnis erhalten. :) :)quelle
hashCode
undequals
.Implementiert in MultiKeyMap mit allgemeinen Sammlungen
quelle
Zwei Möglichkeiten. Verwenden Sie entweder einen kombinierten Schlüssel:
Oder eine Karte der Karte:
quelle
hashCode
undequals
Methoden.Verwenden Sie a
Pair
als Schlüssel für dieHashMap
. JDK hat kein Paar, aber Sie können entweder ein Bibliothekar eines Drittanbieters wie http://commons.apache.org/lang verwenden oder ein eigenes Paar schreiben.quelle
Erstellen Sie eine Wertklasse, die Ihren zusammengesetzten Schlüssel darstellt, z.
Achten Sie darauf, zu überschreiben
equals()
undhashCode()
richtig. Wenn das nach viel Arbeit aussieht, können Sie einige fertige generische Container in Betracht ziehen, wie sie beispielsweisePair
von Apache Commons bereitgestellt werden.Es gibt hier auch viele ähnliche Fragen mit anderen Ideen, wie beispielsweise die Verwendung von Guavas Tabelle , obwohl die Schlüssel unterschiedliche Typen haben können, was in Ihrem Fall (in Bezug auf Speichernutzung und Komplexität) zu viel des Guten sein kann , da ich verstehe, dass Ihre Schlüssel beide Ganzzahlen sind.
quelle
Wenn es sich um zwei Ganzzahlen handelt, können Sie einen schnellen und schmutzigen Trick ausprobieren:
Map<String, ?>
Verwenden Sie den Schlüssel alsi+"#"+j
.Wenn der Schlüssel
i+"#"+j
mitj+"#"+i
try identisch istmin(i,j)+"#"+max(i,j)
.quelle
String
mit komischen Konsequenzen auf denselben abgebildet werden können .i#j = j#i
wenni == j
so die Verwendungmin/max
Trick nicht.5#5
und5#5
vertauscht?5#3
den gleichen Hash wie haben möchten3#5
, dann verwenden Sie min / max, um3#5
in dieser Reihenfolge durchzusetzen .Sie können hierfür auch die Implementierung der Guaventabelle verwenden .
Die Tabelle stellt eine spezielle Zuordnung dar, in der zwei Schlüssel kombiniert angegeben werden können, um auf einen einzelnen Wert zu verweisen. Es ähnelt dem Erstellen einer Karte mit Karten.
quelle
Sie können Ihr Schlüsselobjekt folgendermaßen erstellen:
öffentliche Klasse MapKey {
}}
Dies hat den Vorteil, dass immer sichergestellt ist, dass Sie auch alle Szenarien von Equals abdecken.
HINWEIS : Ihr Schlüssel1 und Schlüssel2 sollten unveränderlich sein. Nur dann können Sie ein stabiles Schlüsselobjekt erstellen.
quelle
Wir können eine Klasse erstellen, die mehr als einen Schlüssel oder Wert übergibt, und das Objekt dieser Klasse kann als Parameter in der Karte verwendet werden.
quelle
Sie können es über den folgenden Link herunterladen: https://github.com/VVS279/DoubleKeyHashMap/blob/master/src/com/virtualMark/doubleKeyHashMap/DoubleKeyHashMap.java
https://github.com/VVS279/DoubleKeyHashMap
Sie können den doppelten Schlüssel verwenden: Wert-Hashmap,
quelle