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

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

 

1. Einführung

In this quick tutorial, we’re going to demonstrate three different approaches for retrieving the key from a map for a given value. Wir werden auch die positiven und negativen Aspekte der verschiedenen Lösungen diskutieren.

Um mehr über dieMap-Schnittstelle zu erfahren, können Siethis article überprüfen.

2. Ein iterativer Ansatz

DieMap-Schnittstelle vonJava Collections bietet eine Methode namensentrySet(). Es gibt alle Einträge oder Schlüssel-Wert-Paare der Karte inSet 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 verweisen.

In diesem Fall fügen wir, wenn ein übereinstimmender Wert gefunden wird, den Schlüssel zuSet hinzu und setzen die Schleife fort. Am Ende geben wir dieSet zurück, die alle gewünschten Schlüssel enthalten:

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,it compares all the entries even if all matches are found after a few iterations.

3. Ein funktionaler Ansatz

With the introduction of Lambda Expressions in Java 8, we can do it in a more flexible and readable way. Wir konvertieren den Eintragssatz inStream und geben ein Lambda an, um nur die Einträge mit dem angegebenen Wert zu filtern.

Dann verwenden wir die Map-Methode, umStream 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);
}

The advantage of returning a stream is that it can cater to a wide range of client needs. Für den aufrufenden Code sind möglicherweise nur ein Schlüssel oder alle Schlüssel erforderlich, die auf den angegebenen Wert zeigen. Da die Auswertung eines Streams faul ist, kann der Client die Anzahl der Iterationen basierend auf seinen Anforderungen steuern.

Darüber hinaus kann der Client den Stream mithilfe eines geeigneten Sammlers 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 oben genannten Ideen wärenif we need to call the functions very frequently for a particular map nicht sehr hilfreich. Es wird unnötigerweise den Satz seiner Schlüssel immer wieder durchlaufen.

In diesem Szenariomaintaining another map of value to the keys would make more sense as it will take constant time to retrieve the key for a value.

DieCommons Collections-Bibliothek vonApache liefert ein solches bidirektionalesMap, das alsBidiMap bezeichnet wird. Es gibt eine Methode namensgetKey() 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");

BidiMap imposes a 1:1 relationship between its keys and values. Wenn wir versuchen, ein Schlüssel-Wert-Paar zu setzen, für das der Wert bereits inMap, vorhanden ist, wird der alte Eintrag entfernt. Mit anderen Worten, der Schlüssel wird anhand des Werts aktualisiert.

Außerdem wird eine größere Menge an Speicher benötigt, um die Reverse-Map zu speichern.

Weitere Informationen zur Verwendung vonBidiMap finden Sie inthis tutorial.

5. Verwendung von Google Guava

We may use another bi-directional Map called BiMap found in Guava developed by Google. Diese Klasse bietet eine Methode mit dem Nameninverse(), um den WertschlüsselMap oder die umgekehrtenMap zum Abrufen des Schlüssels basierend auf einem bestimmten Wert abzurufen:

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

WieBidiMap,BiMap also doesn’t allow multiple keys referring to the same value. Wenn wir versuchen,such an attempt, it zu machen, wirftjava.lang.IllegalArgumentException.

Es ist unnötig zu erwähnen, dassBiMap auch eine erhebliche Menge an Speicher benötigt, da es die inverse Karte darin speichern muss. Wenn Sie mehr überBiMap erfahren möchten, können Sie sichthis tutorial ansehen.

6. Fazit

In diesem kurzen Artikel haben wir einige Methoden zum Abrufen einesMap’s-Schlüssels bei gegebenem Wert erläutert. Jeder Ansatz hat seine eigenen Vor- und Nachteile. Wir sollten immer die Anwendungsfälle berücksichtigen und den am besten geeigneten auswählen, basierend auf der Situation.

Der vollständige Quellcode für das obige Tutorial istover on GitHub verfügbar.