W3docs

Come Iterare una HashMap in Java

Itera le voci di una HashMap Java usando entrySet, keySet, values, forEach e stream.

Una HashMap memorizza coppie chiave-valore e prima o poi è necessario scorrerle - per stampare un report, sommare i valori o filtrare le voci. Java offre diversi modi idiomatici per farlo, ognuno adatto a un'esigenza leggermente diversa: vuoi le chiavi, i valori o entrambi? Questo capitolo tratta gli approcci più comuni - entrySet(), keySet(), values(), forEach e un Iterator con rimozione - e spiega quando usare ciascuno.

Queste tecniche si applicano a qualsiasi implementazione di Map, incluse LinkedHashMap e TreeMap, poiché condividono tutte la stessa API di iterazione.

Scorrere le voci con entrySet()

Quando hai bisogno sia della chiave che del valore, entrySet() è la scelta più efficiente. Restituisce una vista di oggetti Map.Entry e un singolo passaggio fornisce ogni coppia senza una seconda ricerca:

Map<String, Integer> stock = new HashMap<>();
for (Map.Entry<String, Integer> e : stock.entrySet()) {
    System.out.println(e.getKey() + " -> " + e.getValue());
}

Questo è il valore predefinito raccomandato. Usare keySet() e poi chiamare map.get(key) all'interno del ciclo esegue una ricerca hash ridondante per ogni elemento; entrySet() evita completamente questo problema.

Iterare solo chiavi o valori

Se ti interessa solo un lato di ogni coppia, richiedi solo quella vista. keySet() restituisce le chiavi e values() restituisce i valori:

for (String key : stock.keySet()) {
    System.out.println("key: " + key);
}
for (int qty : stock.values()) {
    System.out.println("qty: " + qty);
}

Entrambe le viste sono supportate dalla mappa, quindi riflettono il contenuto corrente senza copiarlo. Usa keySet() quando non hai davvero bisogno dei valori e values() quando le chiavi sono irrilevanti.

Il metodo forEach

Da Java 8, Map dispone di un metodo forEach che accetta un BiConsumer, fornendoti chiave e valore come parametri lambda. È conciso e si legge bene per semplici effetti collaterali:

stock.forEach((key, value) -> System.out.println(key + "=" + value));

Non esiste break o continue all'interno di una lambda, quindi per un'uscita anticipata o un flusso di controllo complesso un classico ciclo for rimane più chiaro.

Rimozione sicura con un Iterator

Modificare strutturalmente una mappa mentre un ciclo for-each la scorre lancia ConcurrentModificationException. Per rimuovere voci durante l'attraversamento, usa un Iterator esplicito e chiama il suo metodo remove():

Iterator<Map.Entry<String, Integer>> it = stock.entrySet().iterator();
while (it.hasNext()) {
    if (it.next().getValue() < 10) {
        it.remove();
    }
}

Un'alternativa moderna è stock.entrySet().removeIf(e -> e.getValue() < 10), che esprime lo stesso filtro in una riga.

ApproccioFornisceIdeale per
entrySet()chiave + valorepredefinito; lettura di entrambi
keySet()solo chiavilavoro con le chiavi
values()solo valoritotali, scansioni di valori
forEachchiave + valore (lambda)effetti collaterali concisi
Iteratorchiave + valorerimozione durante l'attraversamento
java— editable, runs on the server

Cosa osservare dall'esecuzione:

  • Il ciclo entrySet() legge ogni chiave e valore in un singolo passaggio e accumula Total stock: 39, sommando 12 + 7 + 20.
  • keySet() stampa solo le chiavi (apple, banana, cherry) mentre values() stampa solo i numeri, dimostrando che ogni vista espone un solo lato della coppia.
  • La lambda forEach produce le stesse righe chiave=valore del ciclo manuale, confermando che è un equivalente conciso per una semplice iterazione.
  • È stata usata una LinkedHashMap affinché l'output mantenga l'ordine di inserimento - una semplice HashMap non garantisce alcun ordinamento, quindi le righe potrebbero apparire in qualsiasi sequenza.
  • La chiamata Iterator.remove() elimina banana (valore 7, inferiore a 10) e lascia {apple=12, cherry=20}, dimostrando un'eliminazione sicura all'interno del ciclo senza ConcurrentModificationException.

Esercizio

Pratica
Quale metodo consente di accedere sia alla chiave che al valore in una singola iterazione senza una seconda ricerca?
Quale metodo consente di accedere sia alla chiave che al valore in una singola iterazione senza una seconda ricerca?
Was this page helpful?