Wie kann ich den entsprechenden Schlüssel erhalten, wenn ich den Wert habe "foo"
und a HashMap<String> ftw
für den ftw.containsValue("foo")
zurückgegeben true
wird? Muss ich die Hashmap durchlaufen? Was ist der beste Weg das zu tun?
450
public static final String TIME = "time";
undproperties.put(TIME, PbActivityJpa_.time);
Antworten:
Wenn Sie die Commons Collections-Bibliothek anstelle der Standard-Java Collections-API verwenden, können Sie dies problemlos erreichen.
Die BidiMap- Oberfläche in der Sammlungsbibliothek ist eine bidirektionale Zuordnung, mit der Sie einen Schlüssel einem Wert zuordnen können (wie bei normalen Zuordnungen) und einen Wert einem Schlüssel zuordnen können, sodass Sie in beide Richtungen nachschlagen können. Das Abrufen eines Schlüssels für einen Wert wird von der Methode getKey () unterstützt .
Es gibt jedoch eine Einschränkung: Bei Bidi-Karten können nicht mehrere Werte auf Schlüssel abgebildet werden. Daher können Sie keine Bidimaps verwenden, es sei denn, Ihr Datensatz enthält 1: 1-Zuordnungen zwischen Schlüsseln und Werten.
Aktualisieren
Wenn Sie sich auf die Java Collections-API verlassen möchten, müssen Sie die 1: 1-Beziehung zwischen Schlüsseln und Werten zum Zeitpunkt des Einfügens des Werts in die Zuordnung sicherstellen. Das ist leichter gesagt als getan.
Wenn Sie dies sicherstellen können, verwenden Sie die entrySet () -Methode , um die Einträge (Zuordnungen) in der Map abzurufen . Wenn Sie die Menge mit dem Typ Map.Entry erhalten haben , durchlaufen Sie die Einträge, vergleichen Sie den gespeicherten Wert mit dem erwarteten und erhalten Sie den entsprechenden Schlüssel .
Update Nr. 2
Unterstützung für Bidi-Karten mit Generika finden Sie in Google Guava und den überarbeiteten Commons-Collections- Bibliotheken (letzteres ist kein Apache-Projekt). Vielen Dank an Esko für den Hinweis auf die fehlende generische Unterstützung in Apache Commons Collections. Durch die Verwendung von Sammlungen mit Generika wird der Code besser gewartet.
quelle
Wenn Ihre Datenstruktur eine Eins-zu-Eins- Zuordnung zwischen Schlüsseln und Werten aufweist, sollten Sie die Einträge durchlaufen und alle geeigneten Schlüssel auswählen:
Bei einer Eins-zu-Eins- Beziehung können Sie den ersten übereinstimmenden Schlüssel zurückgeben:
In Java 8:
Für Guava-Benutzer kann BiMap auch nützlich sein. Zum Beispiel:
quelle
o(1)
. Wenn Sie die Werte durchlaufen, wird die Leistung beeinträchtigt. Wenn Siebetter performance
eineone-one
Beziehung haben möchten , können Sieanother map
wherevalue is a key
.filter(entry -> entry.getValue().equals(value))
mit , da keine Aussage über die Fähigkeit gemacht wurde. Darüber hinaus können Sie ersetzen mit.filter(entry ->
Objects.equals
(entry.getValue(), value))
null
.map(entry -> entry.getKey())
.map(Map.Entry::getKey)
Einige zusätzliche Informationen ... Kann für Sie nützlich sein
Die obige Methode ist möglicherweise nicht gut, wenn Ihre Hashmap wirklich groß ist. Wenn Ihre Hashmap eine eindeutige Zuordnung von Schlüssel zu eindeutigem Wert enthält, können Sie eine weitere Hashmap verwalten, die eine Zuordnung von Wert zu Schlüssel enthält.
Das heißt, Sie müssen zwei Hashmaps pflegen
In diesem Fall können Sie die zweite Hashmap verwenden, um den Schlüssel abzurufen.
quelle
Ich denke, Ihre Entscheidungen sind
entrySet()
und, um die Schlüssel zu finden, die dem Wert entsprechen. Dies ist die langsamste Methode, da die gesamte Sammlung durchlaufen werden muss, während die beiden anderen Methoden dies nicht erfordern.quelle
Sie können sowohl das Schlüssel-, Wertepaar als auch dessen Umkehrung in Ihre Kartenstruktur einfügen
Wenn Sie map.get ("theValue") verwenden, wird "theKey" zurückgegeben.
Es ist eine schnelle und schmutzige Art, konstante Karten zu erstellen, die nur für einige ausgewählte Datensätze funktionieren:
quelle
Dekorieren Sie die Karte mit Ihrer eigenen Implementierung
quelle
Es gibt keine eindeutige Antwort, da mehrere Schlüssel demselben Wert zugeordnet werden können. Wenn Sie die Eindeutigkeit mit Ihrem eigenen Code erzwingen, besteht die beste Lösung darin, eine Klasse zu erstellen, die zwei Hashmaps verwendet, um die Zuordnungen in beide Richtungen zu verfolgen.
quelle
Um alle Schlüssel zu finden, die diesem Wert zugeordnet sind, durchlaufen Sie alle Paare in der Hashmap mit
map.entrySet()
.quelle
Verwenden von Java 8:
quelle
value=="foo"
das wird nicht funktionieren.equals
sollte verwendet werden, um Strings zu vergleichen.value
es wurde interniert.Wenn Sie die Karte in Ihrem eigenen Code erstellen, versuchen Sie, den Schlüssel und den Wert in der Karte zusammenzufügen:
Wenn Sie dann einen Wert haben, haben Sie auch den Schlüssel.
quelle
Ich denke, dies ist die beste Lösung, ursprüngliche Adresse: Java2s
Eine einfache Verwendung: Wenn Sie alle Daten in hasMap einfügen und item = "Automobile" haben, suchen Sie den Schlüssel in hashMap. das ist eine gute lösung.
quelle
Ich fürchte, Sie müssen nur Ihre Karte iterieren. Am kürzesten konnte ich mir vorstellen:
quelle
quelle
Es hört sich so an, als ob Sie am besten über Einträge iterieren können,
map.entrySet()
da diesmap.containsValue()
wahrscheinlich sowieso der Fall ist.quelle
Für die Android-Entwicklungs-API <19 funktioniert die Eins-zu-Eins-Beziehungslösung von Vitalii Fedorenko nicht, da sie
Objects.equals
nicht implementiert ist. Hier ist eine einfache Alternative:quelle
Sie können Folgendes verwenden:
quelle
Ja, Sie müssen die Hashmap durchlaufen, es sei denn, Sie implementieren etwas in Anlehnung an diese verschiedenen Antworten. Anstatt mit dem entrySet herumzuspielen, würde ich einfach das keySet () abrufen, über dieses Set iterieren und den (ersten) Schlüssel behalten, mit dem Sie Ihren passenden Wert erhalten. Wenn Sie alle Schlüssel benötigen, die diesem Wert entsprechen, müssen Sie natürlich das Ganze tun.
Wie Jonas vorschlägt, ist dies möglicherweise bereits das, was die Methode includesValue tut. Sie können diesen Test also einfach alle zusammen überspringen und jedes Mal die Iteration durchführen (oder der Compiler beseitigt die Redundanz bereits, wer weiß).
Auch relativ zu den anderen Antworten, wenn Ihre umgekehrte Karte aussieht
Sie können sich mit nicht eindeutigen Schlüssel-> Wertzuordnungen befassen, wenn Sie diese Funktion benötigen (sie entwirren). Das würde sich gut in jede der Lösungen einfügen, die hier mit zwei Karten vorgeschlagen werden.
quelle
Sie können den Schlüssel mithilfe von Werten mithilfe des folgenden Codes abrufen.
quelle
quelle
String
als Schlüssel und Wert getestet . Wenn ich anrufe,map.add("1", "2"); map.add("1","3");
kann ich anrufenmap.getKey("2");
und abrufen"1"
, obwohl dies"1"
der Schlüssel für ist"3"
.getValue("1")
wird zurückkehren3
.In Java8
quelle
quelle
quelle
quelle
quelle
Verwenden Sie eine dünne Hülle: HMap
quelle
Meine 2 Cent. Sie können die Schlüssel in einem Array abrufen und dann das Array durchlaufen. Dies wirkt sich auf die Leistung dieses Codeblocks aus, wenn die Karte ziemlich groß ist, wobei Sie zuerst die Schlüssel in einem Array erhalten, was einige Zeit in Anspruch nehmen kann, und dann eine Schleife ausführen. Ansonsten sollte es für kleinere Karten ok sein.
quelle
Ich denke, keySet () ist möglicherweise gut geeignet , um die Schlüssel zu finden, die dem Wert zugeordnet sind, und hat einen besseren Codierungsstil als entrySet () .
Ex:
Angenommen, Sie haben eine HashMap- Zuordnung , ArrayList res , einen Wert , zu dem Sie alle Schlüsselzuordnungen finden möchten , und speichern dann die Schlüssel für die res .
Sie können den folgenden Code schreiben:
anstatt entrySet () unten zu verwenden:
Ich hoffe es hilft :)
quelle
map.get(key) == value
Dies ist keine gute Idee, wenn Sie die Gleichheit von Objekten überprüfen, da Sie Referenzen vergleichen..equals()
Dies beantwortet die Frage zwar nicht direkt, ist aber verwandt.
Auf diese Weise müssen Sie nicht ständig erstellen / iterieren. Erstellen Sie einfach einmal eine umgekehrte Karte und erhalten Sie, was Sie brauchen.
quelle
Es ist wichtig zu beachten, dass Apache Collections seit dieser Frage generische BidiMaps unterstützt . Einige der am besten bewerteten Antworten sind in diesem Punkt nicht mehr korrekt.
Berücksichtigen Sie für eine serialisierte BidiMap, die auch doppelte Werte unterstützt (1-zu-viele-Szenario), auch MapDB.org .
quelle
Wenn Sie den Schlüssel vom Wert erhalten möchten, verwenden Sie am besten Bidimap (bidirektionale Karten). Sie können den Schlüssel vom Wert in O (1) -Zeit erhalten.
Der Nachteil dabei ist jedoch, dass Sie nur eindeutige Schlüssel- und Wertesätze verwenden können.
Es gibt eine Datenstruktur namens Tabelle in Java, die nichts anderes als eine Karte von Karten wie ist
Tabelle <A, B, C> == Karte <A, Karte <B, C >>
Hier können Sie
map<B,C>
durch Abfragen erhaltenT.row(a);
, und Sie können auchmap<A,C>
durch Abfragen erhaltenT.column(b);
Fügen Sie in Ihrem speziellen Fall C als Konstante ein.
Also, es ist wie <a1, b1, 1> <a2, b2, 1>, ...
Wenn Sie also über T.row (a1) ---> die Karte von -> zurückgeben, erhalten Sie das Keyset für diese zurückgegebene Karte.
Wenn Sie den Schlüsselwert suchen müssen, gibt T.column (b2) -> die Karte von -> den Schlüsselsatz der zurückgegebenen Karte zurück.
Vorteile gegenüber dem vorherigen Fall:
quelle