Menu

HashMap in Java: put, get, iterare e schemi comuni

Come usare la HashMap di Java per ricerche chiave-valore: put, get, getOrDefault, containsKey, scorrere le coppie e gli schemi che userai più spesso.

Questa pagina include editor eseguibili: modifica, esegui e vedi subito l'output.

Una mappa memorizza coppie chiave-valore

Una HashMap (di java.util) memorizza associazioni: ogni chiave corrisponde a un valore, e cerchi i valori tramite la loro chiave in un tempo circa costante. Pensa a un dizionario: la parola è la chiave, la definizione è il valore.

I due parametri di tipo sono <KeyType, ValueType>. Qui le chiavi sono String e i valori sono Integer. Come per ArrayList, di solito dichiari la variabile con l'interfaccia Map e costruisci una HashMap.

put, get e sovrascrittura

Due cose da tenere a mente:

  • Una chiave è unica. put con una chiave esistente ne sostituisce il valore e restituisce quello vecchio.
  • get su una chiave mancante restituisce null, non un errore. L'unboxing automatico di quel null in un int lancia una NullPointerException, una fonte comune di bug.

getOrDefault evita la trappola del null

Invece di controllare ogni volta se c'è null, chiedi un valore di riserva:

È il modo più pulito per gestire ricerche di valori "forse presenti", e porta direttamente allo schema più famoso della HashMap.

Contare le occorrenze

Contare quante volte compare ogni elemento è il compito da manuale di una HashMap:

Lo schema map.put(key, map.getOrDefault(key, 0) + 1) si legge come "prendi il conteggio attuale (o zero), aggiungi uno, rimettilo a posto". Un equivalente più ordinato è counts.merge(word, 1, Integer::sum).

Verificare e rimuovere

putIfAbsent(key, value) scrive solo quando la chiave manca: utile per l'inizializzazione pigra.

Scorrere una HashMap

Il ciclo più comune percorre entrySet(), dandoti insieme ogni chiave e valore:

Se ti servono solo le chiavi o solo i valori:

Puoi anche usare forEach con una lambda: ages.forEach((name, age) -> System.out.println(name + ": " + age));.

HashMap non mantiene l'ordine

Una HashMap non garantisce alcun ordine di iterazione: è quello prodotto dall'hashing e può cambiare da un'esecuzione all'altra. Se ti serve un ordine prevedibile:

  • LinkedHashMap mantiene l'ordine di inserimento.
  • TreeMap tiene le chiavi ordinate secondo l'ordine naturale (o secondo un Comparator che fornisci tu).

Tutte e tre implementano l'interfaccia Map, quindi cambiare è una modifica di una riga al costruttore.

Le chiavi devono essere hashabili

HashMap trova le coppie calcolando l'hash della chiave, quindi hashCode() ed equals() di una chiave devono essere coerenti. I tipi predefiniti come String e Integer lo fanno già correttamente. Se usi una tua classe come chiave, fai l'override sia di equals sia di hashCode, altrimenti due oggetti "uguali" nel significato finiranno in bucket diversi e le tue ricerche falliranno in modo misterioso.

Prossimo passo: HashSet

Una HashMap risponde alla domanda "quale valore è memorizzato sotto questa chiave?". Quando ti interessa solo sapere se qualcosa è presente, cioè un insieme di valori unici senza dati associati, lo strumento giusto è HashSet, il prossimo argomento.

Domande frequenti

Come si crea una HashMap in Java?

Dichiarala con due parametri di tipo, il tipo della chiave e il tipo del valore, e chiama il costruttore: Map<String, Integer> ages = new HashMap<>();. Poi aggiungi coppie con ages.put("Ada", 36); e leggile con ages.get("Ada");. Importa java.util.HashMap e java.util.Map.

Come si scorre una HashMap in Java?

Scorri map.entrySet() con un ciclo for-each per ottenere insieme ogni chiave e valore: for (Map.Entry<String, Integer> e : map.entrySet()) { ... }, leggendo e.getKey() ed e.getValue(). Puoi anche scorrere map.keySet() per le sole chiavi o map.values() per i soli valori. Nota che una HashMap non mantiene l'ordine di inserimento.

Qual è la differenza tra get e getOrDefault?

get(key) restituisce il valore di una chiave, oppure null se la chiave non c'è, e questo può portare a una NullPointerException se usi direttamente il risultato. getOrDefault(key, fallback) restituisce il valore se presente, altrimenti il valore di riserva che passi, così eviti il controllo su null. È particolarmente comodo per contare: counts.put(c, counts.getOrDefault(c, 0) + 1).

Illustrazione dei linguaggi di programmazione di Coddy

Impara a programmare con Coddy

INIZIA