CodeGym /Java Blog /Random-IT /HashMap: che tipo di mappa è questa?
John Squirrels
Livello 41
San Francisco

HashMap: che tipo di mappa è questa?

Pubblicato nel gruppo Random-IT
CIAO! In questa lezione, esamineremo più da vicino Java HashMap . In precedenza, abbiamo studiato le strutture dati in cui gli elementi sono archiviati come se stessi. In un array o in un ArrayList / LinkedList , memorizziamo un certo numero di elementi. Ma cosa succede se il nostro compito cambia un po'?
HashMap: che tipo di mappa è questa?  - 1
Immagina la seguente attività: crea un elenco di 100 persone che memorizzi il nome e il numero di passaporto di ciascuna persona. In linea di principio, non è così difficile. Ad esempio, puoi inserire entrambi in una stringa e quindi creare un elenco di queste stringhe: "Amelia Aguilar, 4211 717171". Ma questa soluzione ha due inconvenienti. Innanzitutto, potremmo aver bisogno della possibilità di cercare per numero di passaporto. E questo sarà problematico dato questo formato di archiviazione delle informazioni. In secondo luogo, nulla ci impedisce di creare due persone diverse con lo stesso numero di passaporto. E questo è il difetto più grave della nostra soluzione. Questo non dovrebbe mai essere consentito: non esistono due persone con lo stesso numero di passaporto. Ci viene in aiuto una nuova struttura dati: Map. È anche noto come "array associativo", ma questo termine è usato raramente. Più comunemente, è chiamato "dizionario" o "mappa". :) In che modo è fondamentalmente diverso dalle strutture di dati che abbiamo considerato in precedenza? Soprattutto, nel fatto che i dati in una mappa sono memorizzati come coppie chiave-valore. Qualsiasi cosa può servire come chiavi e valori: numeri, stringhe o oggetti di altre classi. Oggi studieremo l'implementazione più comune della classe Map : Java HashMap . HashMap: che tipo di mappa è questa?  - 2

Quindi, cosa dobbiamo sapere su HashMap in Java?

È molto facile creare:

public static void main(String[] args) {
   HashMap<Integer, String> passportsAndNames = new HashMap<>();
}
Qui creiamo un dizionario che memorizza gli elementi come coppie "numero-stringa". Il numero fungerà da chiave e la stringa da valore. Inoltre specifichiamo il tipo di chiave (Integer) e il tipo di valore (String). Perché? Innanzitutto, una chiave HashMap è sempre univoca. Questo ci si addice perfettamente, poiché possiamo utilizzare il numero del passaporto come chiave ed evitare duplicati. Il valore sarà una stringa con il nome completo (persone diverse possono avere lo stesso nome; non c'è nulla di cui preoccuparsi). L'aggiunta di una nuova coppia alla HashMap si presenta così:

public class Main {

   public static void main(String[] args) {
       HashMap<Integer, String> passportsAndNames = new HashMap<>();

       passportsAndNames.put (212133, "Bridget Logan");
       passportsAndNames.put (162348, "Ivan the Great");
       passportsAndNames.put(8082771, "Donald John Trump");
       System.out.println(passportsAndNames);
   }
}
Usiamo il metodo put() per questo. Inoltre, HashMap sovrascrive il metodo toString() , quindi può essere visualizzato sulla console. L'output sarà simile a questo: {212133=Bridget Logan, 8082771=Donald John Trump, 162348=Ivan the Great} Ora verifichiamo se le chiavi sono davvero univoche? Proviamo ad aggiungere un nuovo elemento con una chiave che è già stata utilizzata nella mappa:

public static void main(String[] args) {
   HashMap<Integer, String> passportsAndNames = new HashMap<>();

   passportsAndNames.put (212133, "Bridget Logan");
   passportsAndNames.put (162348, "Ivan the Great");
   passportsAndNames.put(8082771, "Donald John Trump");
   passportsAndNames.put(162348, "Albert Kent");// This key has already been used
   System.out.println(passportsAndNames);
}
Output: {212133=Bridget Logan, 8082771=Donald John Trump, 162348=Albert Kent} Come puoi vedere, il valore precedente associato alla chiave 162348 è stato sovrascritto. Usiamo il termine "chiave" per un motivo. Si accede ai valori in una HashMap utilizzando la chiave, ma non viceversa. La chiave non può essere ottenuta utilizzando un valore, poiché i valori potrebbero non essere univoci. Questo può essere visto chiaramente quando si ottiene o si rimuove un elemento da HashMap :

public static void main(String[] args) {
   HashMap<Integer, String> passportsAndNames = new HashMap<>();

   passportsAndNames.put (212133, "Bridget Logan");
   passportsAndNames.put (162348, "Ivan the Great");
   passportsAndNames.put(8082771, "Donald John Trump");

   String lidiaName = passportsAndNames.get(212133);
   System.out.println(lidiaName);

   passportsAndNames.remove(162348);
   System.out.println(passportsAndNames);
}
Per ottenere un valore o rimuovere una coppia dal dizionario, dobbiamo passare a get() e remove() la chiave univoca che corrisponde al valore. A differenza degli array e degli elenchi, una HashMap in Java non ha indici numerici: si accede ai valori utilizzando la chiave. Output della console: Bridget Logan {212133=Bridget Logan, 8082771=Donald John Trump} Le classi ArrayList e LinkedList ci consentono di verificare se l'elenco contiene un particolare elemento. Java HashMap ci consente di farlo. Inoltre, possiamo farlo per entrambi i membri della coppia: Questo è ciò che containsKey() (cerca una chiave) e containsValue()(controlla per un valore) i metodi sono per.

public static void main(String[] args) {
   HashMap<Integer, String> passportsAndNames = new HashMap<>();

   passportsAndNames.put (212133, "Bridget Logan");
   passportsAndNames.put (162348, "Ivan the Great");
   passportsAndNames.put(8082771, "Donald John Trump");

   System.out.println(passportsAndNames.containsKey(11111));
   System.out.println(passportsAndNames.containsValue("Donald John Trump"));
}
Output: false true Un'altra caratteristica utile di HashMap in Java è il fatto che è possibile ottenere elenchi separati di tutte le chiavi e di tutti i valori. Ciò si ottiene con i metodi keySet() e values() :

public class Main {

   public static void main(String[] args) {
       HashMap<Integer, String> passportsAndNames = new HashMap<>();

       passportsAndNames.put (212133, "Bridget Logan");
       passportsAndNames.put (162348, "Ivan the Great");
       passportsAndNames.put(8082771, "Donald John Trump");

       Set keys = passportsAndNames.keySet();
       System.out.println("Keys: " + keys);

       ArrayList<String> values = new ArrayList<>(passportsAndNames.values());
       System.out.println("Values: " + values);
   }
}
Le chiavi vengono estratte in un Set , che non abbiamo ancora trattato. È speciale in quanto non può contenere elementi ripetuti. Ora la cosa principale è ricordare che l'elenco di tutte le chiavi può essere recuperato da una HashMap in una raccolta separata. Nell'esempio, abbiamo salvato i valori in un normale ArrayList . Output della console: Chiavi: [212133, 8082771, 162348] Valori: [Bridget Logan, Donald John Trump, Ivan il Grande] I metodi size() e clear() fanno esattamente la stessa cosa delle strutture precedenti che abbiamo discusso: il primo restituisce il numero di elementi attualmente presenti nel dizionario, il secondo rimuove tutti gli elementi.

public static void main(String[] args) {
   HashMap<Integer, String> passportsAndNames = new HashMap<>();

   passportsAndNames.put (212133, "Bridget Logan");
   passportsAndNames.put (162348, "Ivan the Great");
   passportsAndNames.put(8082771, "Donald John Trump");

   System.out.println(passportsAndNames.size());
   passportsAndNames.clear();
   System.out.println(passportsAndNames);
}
Output: 3 {} Per verificare se c'è almeno un elemento nella nostra HashMap , possiamo usare il metodo isEmpty() :

public static void main(String[] args) {
   HashMap<Integer, String> passportsAndNames = new HashMap<>();

   passportsAndNames.put (212133, "Bridget Logan");
   passportsAndNames.put (162348, "Ivan the Great");
   passportsAndNames.put(8082771, "Donald John Trump");

   if (!passportsAndNames.isEmpty()) {

       System.out.println(passportsAndNames);
   }
}
Output: {212133=Bridget Logan, 8082771=Donald John Trump, 162348=Ivan the Great} Ora l'output verrà inviato alla console solo dopo un controllo preliminare. :) Un altro punto interessante è che due mappe possono essere combinate in una sola. Ciò è stato ottenuto utilizzando il metodo putAll() . Lo chiamiamo sul primo HashMap , passiamo il secondo come argomento e gli elementi del secondo vengono aggiunti al primo:

public static void main(String[] args) {
   HashMap<Integer, String> passportsAndNames = new HashMap<>();
   HashMap<Integer, String> passportsAndNames2 = new HashMap<>();

   passportsAndNames.put (212133, "Bridget Logan");
   passportsAndNames.put (162348, "Ivan the Great");
   passportsAndNames.put(8082771, "Donald John Trump");

   passportsAndNames2.put(917352, "Clifford Patrick");
   passportsAndNames2.put(925648, "Mitchell Salgado");

   passportsAndNames.putAll(passportsAndNames2);
   System.out.println(passportsAndNames);
}
Output: {917352=Clifford Patrick, 212133=Bridget Logan, 8082771=Donald John Trump, 925648=Mitchell Salgado, 162348=Ivan the Great} Tutte le coppie in passportsAndNames2 sono state copiate in passportsAndNames . Consideriamo ora un esempio più complicato. Nello specifico, l'iterazione su una HashMap in un ciclo.

for (Map.Entry<Integer, String> entry: passportsAndNames.entrySet()) {
   System.out.println(entry);
}
La classe Map.Entry denota la coppia chiave-valore all'interno del dizionario. Il metodo entrySet() restituisce un elenco di tutte le coppie nella nostra HashMap . Poiché la nostra mappa consiste di queste coppie Map.Entry , stiamo iterando sulle coppie, non su chiavi o valori separati. Output: 212133=Bridget Logan 8082771=Donald John Trump 162348=Ivan the Great Inoltre, non dimenticare di studiare la documentazione ufficiale di Oracle per HashMap .
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION