1. Un set de perechi cheie-valoare.

Un set de perechi cheie-valoare

În Java, o altă colecție interesantă (în linii mari) este Map. Uneori, această structură de date este numită și dicționar.

Este similar cu Setcolecția, dar stochează un set de „perechi” de elemente, mai degrabă decât un set de elemente. Fiecare pereche dintr-o Mapconstă din două elemente: o „cheie” și o „valoare”.

Să presupunem că doriți ca programul dvs. să stocheze numele angajaților și salariile acestora sau numele colegilor și vârstele acestora. Atunci ai nevoie de un tabel ca acesta:

Nume Vârstă
Elon 21
Jeff 22
Factură 48
Warren ?

Fiecare rând conține câteva valori. Ne vom referi la nume ca fiind cheia perechii , iar vârsta ca valoare a perechii .

Întregul set al acestor perechi este harta noastră ( Map).

Cheia unei perechi poate fi orice, cu excepția null. Cheile trebuie să fie unice: o hartă nu poate conține două chei identice.


2. HashMapclasa

Clasa HashMapeste cel mai popular tip de Mapcolecție. Pe de o parte, este foarte asemănător cu HashSet și are toate metodele sale. Pe de altă parte, este ca o listă ( ArrayList) care poate folosi cuvinte (sau orice altceva) ca indici.

Puteți crea o HashMapdeclarație folosind o declarație ca aceasta:

HashMap<KeyType, ValueType> name = new HashMap<KeyType, ValueType>();

Unde KeyTypeeste tipul cheilor din perechile stocate și ValueTypeeste tipul valorilor din perechile stocate în HashMapcolecție.

Clasa HashMapare metode ca aceasta:

Metodă Descriere
void put(KeyType key, ValueType value)
Adaugă perechea ( key, value) la colecție
ValueType get(KeyType key)
Returnează valoarea asociată cu o cheie.
boolean containsKey(KeyType key)
Verifică dacă o cheie există în colecție
boolean containsValue(ValueType value)
Verifică existența unei valori în colecție
ValueType remove(KeyType key)
Elimină un element din colecție
void clear()
Șterge colecția, eliminând toate elementele
int size()
Returnează numărul de perechi cheie-valoare din colecție
Set<KeyType> keySet()
Returnează setul de chei din colecție
Collection<ValueType> values()
Returnează un set care conține elementele colecției
Set<Map.Entry<KeyType, ValueType>> entrySet()
Returnează un set ( Set) de toate perechile ( Map.Entry) din colecție.

Adăugarea de elemente la aHashMap

Elementele sunt adăugate la o hartă ca perechi folosind put()metoda. Cheia este transmisă ca prim argument, iar valoarea este transmisă ca al doilea.

HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("Elon", 21);
map.put("Jeff", 22);
map.put("Bill", 48);
map.put("Warren", null);

Când adăugați o pereche cheie-valoare, dacă cheia există deja în colecție, atunci valoarea veche este înlocuită cu noua valoare.

Acest comportament face HashMapca o matrice sau o listă ai cărei indici sunt cuvinte ( String) în loc de numere.

Important:

Aproape orice tip poate fi KeyType sau ValueType. Există câteva mici cerințe suplimentare pentru KeyType și veți afla despre ele când studiați colecțiile mai detaliat în misiunea Java Collections.



3. Subseturile lui a HashMap: setul de chei

Să presupunem că vrem doar să afișăm toate intrările într-o HashMappe ecran. Cum facem asta? Pentru a face acest lucru, trebuie să știm cum să parcurgem toate intrările din HashMap. Acest lucru se poate face în mai multe moduri.

Cel mai simplu mod este să treceți peste taste

HashMapintrările nu sunt numerotate secvenţial, deci o buclă cu un contor nu va funcţiona aici. Dar putem obține un set de chei folosind keySet()metoda și știți deja cum să repetați un set:

Cod Descriere
HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("Elon", 21);
map.put("Jeff", 22);
map.put("Bill", 48);
map.put("Warren", null);

for (String key: map.keySet())
{
   Integer value = map.get(key);
   System.out.println(key + " --> " + value);
}






Buclă peste cheile de la map

Obține valoarea asociată cheii

Metoda keySet()returnează un set de chei. Puteți utiliza acest set în două moduri:

Notație compactă Notație lungă
for (String key: map.keySet())
{
   Integer value = map.get(key);
   System.out.println(key + " --> " + value);
}
Set<String> keys = map.keySet();

for (String key: keys)
{
   Integer value = map.get(key);
   System.out.println(key + " --> " + value);
}


4. Buclă peste perechi cheie-valoare

Există, de asemenea, o modalitate mai complicată: puteți transforma a Mapîntr-un set de perechi cheie-valoare și apoi treceți în buclă peste elementele setului, așa cum am aflat deja.

Colecția HashMapare o clasă de ajutor care stochează o pereche cheie-valoare. Arata cam asa:

class Entry<KeyType, ValueType>
{
   private KeyType key;
   private ValueType value;

   public KeyType getKey()
   {
      return this.key;
   }

   public ValueType getValue()
   {
      return this.value;
   }
}

Rezultatul apelării entrySet()metodei pe un obiect va fi :HashMap<KeyType, ValueType>Set<Entry<KeyType, ValueType>>

Set<Entry<KeyType, ValueType>> name = map.entrySet();

Aici avem Setclasa generică cu un parametru de tip, care la rândul său este un tip generic ( Entry) cu doi parametri de tip.

Este foarte ușor pentru un începător să se încurce în această privință. Dar odată ce îți dai seama, poți scrie cod ca:

HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("Elon", 21);
map.put("Jeff", 22);
map.put("Bill", 48);
map.put("Warren", null);

Set<Map.Entry<String, Integer>> entries = map.entrySet();
for(Map.Entry<String, Integer> pair: entries)
{
   String key = pair.getKey();
   Integer value = pair.getValue();
   System.out.println(key + " --> " + value);
}

Acestea fiind spuse, acest cod poate fi puțin simplificat:

În primul rând, puteți sări peste crearea unei variabile separate entriesși, în schimb, puteți apela entrySet()metoda direct în forbucla:

for(Map.Entry<String, Integer> pair: map.entrySet())
{
   String key = pair.getKey();
   Integer value = pair.getValue();
   System.out.println(key + " --> " + value);
}

În al doilea rând, puteți utiliza varoperatorul recent introdus pentru a deduce automat tipul perechii cheie-valoare :

for(var pair: map.entrySet())
{
   String key = pair.getKey();
   Integer value = pair.getValue();
   System.out.println(key + " --> " + value);
}

Nu-i rău, nu?



5. Comparația ArrayListșiHashMap

A HashMapseamănă foarte mult cu un ArrayListcare permite ca șirurile de caractere (sau alte tipuri) să fie folosite ca indici (cheile).

Dacă utilizați Integerpentru cheile într-un HashMap, atunci devine și mai asemănător cu un ArrayList. Să comparăm:

Codați cu ArrayList<String> Codați cu HashMap<Integer, String>
ArrayList<String> list = new ArrayList<String>();

list.add("Greetings");
list.add("Hello");

String s = list.get(0);
list.set(0, s + "!");

for (String item: list)
{
   System.out.println(item);
}
HashMap<Integer, String> map = new HashMap<Integer, String>();

map.put(0, "Greetings");
map.put(1, "Hello");

String s = map.get(0);
map.put(0, s + "!");

for (String item: map.values())
{
   System.out.println(item);
}