Holen Sie sich den Schlüssel für einen Wert aus einer Java Map

1. Einleitung

In diesem kurzen Tutorial werden drei verschiedene Ansätze zum Abrufen des Schlüssels von einer Karte für einen bestimmten Wert demonstriert. Wir werden auch die positiven und negativen Aspekte der verschiedenen Lösungen diskutieren.

Weitere Informationen zur Kartenoberfläche finden Sie in diesem Artikel.

2. Ein iterativer Ansatz

Die Map- Oberfläche von Java Collections bietet eine Methode namens entrySet () . Es gibt alle Einträge oder Schlüssel-Wert-Paare der Karte in einem Set zurück .

Die Idee ist, diesen Eintragssatz zu durchlaufen und den Schlüssel zurückzugeben, für den der Wert mit dem angegebenen Wert übereinstimmt:

public  K getKey(Map map, V value) { for (Entry entry : map.entrySet()) { if (entry.getValue().equals(value)) { return entry.getKey(); } } return null; }

Es besteht jedoch die Möglichkeit, dass mehrere Schlüssel auf denselben Wert zeigen.

Wenn in diesem Fall ein übereinstimmender Wert gefunden wird, fügen wir den Schlüssel einem Set hinzu und setzen die Schleife fort. Am Ende geben wir das Set zurück, das alle gewünschten Schlüssel enthält:

public  Set getKeys(Map map, V value) { Set keys = new HashSet(); for (Entry entry : map.entrySet()) { if (entry.getValue().equals(value)) { keys.add(entry.getKey()); } } return keys; }

Obwohl dies eine sehr einfache Implementierung ist, werden alle Einträge verglichen, auch wenn nach einigen Iterationen alle Übereinstimmungen gefunden wurden.

3. Ein funktionaler Ansatz

Mit der Einführung von Lambda Expressions in Java 8 können wir dies flexibler und lesbarer machen. Wir konvertieren den Eintragssatz in einen Stream und liefern ein Lambda, um nur die Einträge mit dem angegebenen Wert zu filtern.

Dann verwenden wir die Map-Methode, um einen Stream der Schlüssel aus den gefilterten Einträgen zurückzugeben:

public  Stream keys(Map map, V value) { return map .entrySet() .stream() .filter(entry -> value.equals(entry.getValue())) .map(Map.Entry::getKey); }

Der Vorteil der Rückgabe eines Streams besteht darin, dass er eine Vielzahl von Kundenanforderungen erfüllen kann. Der aufrufende Code erfordert möglicherweise nur einen Schlüssel oder alle Schlüssel, die auf den angegebenen Wert zeigen. Da die Auswertung eines Streams verzögert ist, kann der Client die Anzahl der Iterationen basierend auf seinen Anforderungen steuern.

Darüber hinaus kann der Client den Stream mit einem geeigneten Kollektor in eine beliebige Sammlung konvertieren:

Stream keyStream1 = keys(capitalCountryMap, "South Africa"); String capital = keyStream1.findFirst().get(); Stream keyStream2 = keys(capitalCountryMap, "South Africa"); Set capitals = keyStream2.collect(Collectors.toSet());

4. Verwenden von Apache Commons-Sammlungen

Die obigen Ideen wären nicht sehr hilfreich, wenn wir die Funktionen für eine bestimmte Karte sehr häufig aufrufen müssten . Es wird den Satz seiner Schlüssel unnötigerweise immer wieder wiederholen.

In diesem Szenario wäre es sinnvoller , eine andere Wertzuordnung zu den Schlüsseln beizubehalten, da das Abrufen des Schlüssels für einen Wert konstant lange dauert.

Die Commons Collections- Bibliothek von Apache bietet eine solche bidirektionale Karte namens BidiMap . Es hat eine Methode namens getKey () zum Abrufen eines Schlüssels für einen bestimmten Wert:

BidiMap capitalCountryMap = new DualHashBidiMap(); capitalCountryMap.put("Berlin", "Germany"); capitalCountryMap.put("Cape Town", "South Africa"); String capitalOfGermany = capitalCountryMap.getKey("Germany");

Allerdings BidiMap erlegt eine 1: 1 - Beziehung zwischen den Schlüsseln und Werten . Wenn wir versuchen, ein Schlüssel-Wert-Paar einzufügen, für das der Wert bereits in der Map vorhanden ist, wird der alte Eintrag entfernt. Mit anderen Worten, der Schlüssel wird gegen den Wert aktualisiert.

Außerdem ist mehr Speicher erforderlich, um die umgekehrte Zuordnung beizubehalten.

Weitere Informationen zur Verwendung einer BidiMap finden Sie in diesem Tutorial.

5. Verwenden von Google Guava

Wir können eine andere bidirektionale Karte namens BiMap verwenden, die in Guava von Google entwickelt wurde. Diese Klasse stellt eine Methode namens Inverse () die Wert-Schlüssel zu bekommen Karte oder umgekehrt Karte der Schlüssel zu holen auf einem bestimmten Wert zugrunde gelegt :

HashBiMap capitalCountryMap = HashBiMap.create(); capitalCountryMap.put("Berlin", "Germany"); capitalCountryMap.put("Cape Town", "South Africa"); String capitalOfGermany = capitalCountryMap.inverse().get("Germany");

Wie BidiMap , bimap erlaubt auch nicht mehr Tasten mit Bezug auf den gleichen Wert . Wenn wir versuchen, einen solchen Versuch zu unternehmen, wird eine java.lang.IllegalArgumentException ausgelöst .

Unnötig zu erwähnen , dass BiMap auch eine erhebliche Menge an Speicher benötigt, da die inverse Karte darin gespeichert werden muss. Wenn Sie mehr über BiMap erfahren möchten , können Sie dieses Tutorial lesen .

6. Fazit

In diesem kurzen Artikel haben wir einige Methoden zum Abrufen des Schlüssels einer Karte unter Berücksichtigung des Werts erläutert . Jeder Ansatz hat seine eigenen Vor- und Nachteile. Wir sollten immer die Anwendungsfälle berücksichtigen und je nach Situation den am besten geeigneten auswählen.

Der vollständige Quellcode für das obige Tutorial ist auf GitHub verfügbar.