Obțineți cheia pentru o valoare dintr-o hartă Java

1. Introducere

În acest tutorial rapid, vom demonstra trei abordări diferite pentru extragerea cheii dintr-o hartă pentru o valoare dată. De asemenea, vom discuta despre pozitivele și negativele diferitelor soluții.

Pentru a afla mai multe despre interfața Hartă , puteți consulta acest articol.

2. O abordare iterativă

Harta Interfața Java Colecții oferă o metodă numită entrySet () . Returnează toate intrările sau perechile cheie-valoare ale hărții dintr-un set .

Ideea este să iterați peste acest set de intrări și să returnați cheia pentru care valoarea se potrivește cu valoarea furnizată:

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

Cu toate acestea, ar putea exista posibilitatea ca mai multe taste să indice aceeași valoare.

În acest caz, dacă se găsește o valoare potrivită, adăugăm cheia la un set și continuăm bucla. La final, returnăm setul care conține toate tastele dorite:

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; }

Deși aceasta este o implementare foarte simplă, compară toate intrările, chiar dacă toate potrivirile se găsesc după câteva iterații.

3. O abordare funcțională

Odată cu introducerea expresiilor Lambda în Java 8, o putem face într-un mod mai flexibil și mai ușor de citit. Convertim setul de intrări într-un Stream și furnizăm un lambda pentru a filtra numai acele intrări cu valoarea dată.

Apoi folosim metoda hărții pentru a returna un flux de taste din intrările filtrate:

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

Avantajul returnării unui flux este că poate satisface o gamă largă de nevoi ale clienților. Codul de apel poate necesita o singură tastă sau toate tastele care indică valoarea furnizată. Deoarece evaluarea unui flux este leneșă, clientul poate controla numărul de iterații pe baza cerințelor sale.

În plus, clientul poate converti fluxul în orice colecție folosind un colector adecvat:

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

4. Utilizarea colecțiilor Apache Commons

Ideile de mai sus nu ar fi de mare ajutor dacă ar trebui să apelăm funcțiile foarte frecvent pentru o anumită hartă . Va itera în mod inutil setul de taste din nou și din nou.

În acest scenariu, menținerea unei alte hărți a valorii cheilor ar avea mai mult sens, deoarece va fi nevoie de timp constant pentru a recupera cheia pentru o valoare.

Biblioteca Commons Collections de Apache oferă o astfel de hartă bidirecțională numită BidiMap . Are o metodă numită getKey () pentru recuperarea unei chei pentru o anumită valoare:

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

Cu toate acestea, BidiMap impune o relație 1: 1 între cheile și valorile sale . Dacă încercăm să punem o pereche cheie-valoare pentru care valoarea există deja în hartă, aceasta elimină intrarea veche. Cu alte cuvinte, actualizează cheia în raport cu valoarea.

De asemenea, necesită o cantitate mai mare de memorie pentru a păstra harta inversă.

Mai multe detalii despre modul de utilizare a BidiMap sunt în acest tutorial.

5. Utilizarea Google Guava

Putem folosi o altă hartă bidirecțională numită BiMap găsită în Guava dezvoltată de Google. Această clasă oferă o metodă numită inversă () pentru a obține cheia valoare- hartă sau harta inversă pentru a prelua cheia pe baza unei valori date:

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

La fel ca BidiMap , BiMap nu permite , de asemenea, mai multe taste referitoare la aceeași valoare . Dacă încercăm să facem o astfel de încercare, aceasta aruncă o excepție java.lang.IllegalArgumentException .

Inutil să spun că BiMap folosește, de asemenea, o cantitate semnificativă de memorie, deoarece trebuie să stocheze harta inversă în interior. Dacă sunteți interesat să aflați mai multe despre BiMap , puteți consulta acest tutorial.

6. Concluzie

În acest scurt articol, am discutat câteva metode de recuperare a cheii unei hărți, având în vedere valoarea. Fiecare abordare are propriile argumente pro și contra. Ar trebui să luăm întotdeauna în considerare cazurile de utilizare și să îl alegem pe cel mai potrivit în funcție de situație.

Codul sursă complet pentru tutorialul de mai sus este disponibil pe GitHub.