Haal de sleutel voor een waarde op van een Java-kaart

1. Inleiding

In deze korte tutorial demonstreren we drie verschillende benaderingen voor het ophalen van de sleutel van een kaart voor een bepaalde waarde. We bespreken ook de positieve en negatieve punten van de verschillende oplossingen.

Voor meer informatie over het Kaart interface, kunt u dit artikel lezen.

2. Een iteratieve benadering

De Kaart interface van Java-verzamelingen biedt een methode genaamd entrySet (). Het retourneert alle items of sleutel / waarde-paren van de kaart in een Set.

Het idee is om deze entry-set te herhalen en de sleutel te retourneren waarvoor de waarde overeenkomt met de opgegeven waarde:

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

Het is echter mogelijk dat meerdere sleutels naar dezelfde waarde verwijzen.

Als in dat geval een overeenkomende waarde wordt gevonden, voegen we de sleutel toe aan een Set en ga door met de lus. Uiteindelijk retourneren we de Set met alle gewenste sleutels:

public GetKeys instellen (Map map, V-waarde) {Set keys = new HashSet (); for (Entry entry: map.entrySet ()) {if (entry.getValue (). equals (waarde)) {keys.add (entry.getKey ()); }} return-toetsen; }

Hoewel dit een zeer ongecompliceerde implementatie is, het vergelijkt alle inzendingen, zelfs als alle overeenkomsten zijn gevonden na een paar iteraties.

3. Een functionele benadering

Met de introductie van Lambda Expressions in Java 8 kunnen we dit flexibeler en leesbaarder doen. We converteren de entry-set naar een Stroom en geef een lambda om alleen die items met de opgegeven waarde te filteren.

Vervolgens gebruiken we de map-methode om een Stroom van de sleutels uit de gefilterde items:

openbare streamsleutels (Mapmap, V-waarde) {return map .entrySet () .stream () .filter (entry -> value.equals (entry.getValue ())) .map (Map.Entry :: getKey); }

Het voordeel van het retourneren van een stream is dat deze kan voorzien in een breed scala aan klantbehoeften. De aanroepcode vereist mogelijk slechts één sleutel of alle sleutels die naar de opgegeven waarde wijzen. Omdat de evaluatie van een stream lui is, kan de klant het aantal iteraties regelen op basis van de vereiste.

Bovendien kan de klant de stream converteren naar elke verzameling met behulp van een geschikt verzamelprogramma:

Stream keyStream1 = keys (capitalCountryMap, "Zuid-Afrika"); Tekenreekshoofdstad = keyStream1.findFirst (). Get (); Stream keyStream2 = keys (capitalCountryMap, "Zuid-Afrika"); Stel hoofdletters in = keyStream2.collect (Collectors.toSet ());

4. Apache Commons-verzamelingen gebruiken

De bovenstaande ideeën zouden niet erg nuttig zijn als we de functies heel vaak moeten aanroepen voor een bepaalde kaart. Het zal de set van zijn sleutels onnodig keer op keer herhalen.

In dit scenario, het behouden van een andere waardetoewijzing voor de sleutels zou logischer zijn omdat het constant tijd kost om de sleutel voor een waarde op te halen.

De Commons Collecties bibliotheek door Apache voorziet in een dergelijke bidirectionele Kaart gebeld BidiMap. Het heeft een methode met de naam getKey () voor het ophalen van een sleutel voor een bepaalde waarde:

BidiMap capitalCountryMap = nieuwe DualHashBidiMap (); capitalCountryMap.put ("Berlijn", "Duitsland"); capitalCountryMap.put ("Kaapstad", "Zuid-Afrika"); String capitalOfGermany = capitalCountryMap.getKey ("Duitsland");

Echter, BidiMap legt een 1: 1 relatie op tussen zijn sleutels en waarden. Als we proberen een sleutel / waarde-paar te plaatsen waarvan de waarde al bestaat in het Kaart, het verwijdert de oude vermelding. Met andere woorden, het werkt de sleutel bij met de waarde.

Het vereist ook een grotere hoeveelheid geheugen om de omgekeerde kaart te behouden.

Meer informatie over het gebruik van een BidiMap staan ​​in deze tutorial.

5. Google Guava gebruiken

We kunnen een andere bidirectionele gebruiken Kaart gebeld BiMap gevonden in Guava ontwikkeld door Google. Deze klasse biedt een methode met de naam inverse () om de waarde-sleutel te krijgen Kaart of omgekeerd Kaart om de sleutel op te halen op basis van een bepaalde waarde:

HashBiMap capitalCountryMap = HashBiMap.create (); capitalCountryMap.put ("Berlijn", "Duitsland"); capitalCountryMap.put ("Kaapstad", "Zuid-Afrika"); String capitalOfGermany = capitalCountryMap.inverse (). Get ("Duitsland");

Leuk vinden BidiMap, BiMap staat ook niet toe dat meerdere sleutels naar dezelfde waarde verwijzen. Als we een dergelijke poging proberen te doen, gooit het een java.lang.IllegalArgumentException .

Onnodig te zeggen, BiMap gebruikt ook een aanzienlijke hoeveelheid geheugen omdat het de inverse kaart erin moet opslaan. Als u meer wilt weten over BiMap, kun je deze tutorial bekijken.

6. Conclusie

In dit korte artikel hebben we enkele methoden besproken om een Kaart's key gezien de waarde. Elke benadering heeft zijn eigen voor- en nadelen. We moeten altijd de use-cases overwegen en de meest geschikte kiezen op basis van de situatie.

De volledige broncode voor de bovenstaande tutorial is beschikbaar op GitHub.