CodeGym /Corsi /JAVA 25 SELF /Map: HashMap e TreeMap, chiavi e valori

Map: HashMap e TreeMap, chiavi e valori

JAVA 25 SELF
Livello 26, Lezione 2
Disponibile

1. Introduzione

Nella vita reale ci imbattiamo spesso in situazioni in cui a ogni «chiave» unica bisogna associare un certo «valore». Una rubrica telefonica conserva il numero di telefono e il nome di una persona, un dizionario collega una parola alla sua traduzione, e in un registro dei voti ogni studente ha il proprio nome e il voto corrispondente.

In Java per questi compiti c’è l’interfaccia Map. È una collezione che memorizza coppie «chiave — valore» (key-value pair).

Proprietà principali di Map:

  • Ogni chiave è unica (non sono ammessi duplicati).
  • A una chiave può corrispondere un solo valore.
  • I valori possono ripetersi.

Immaginiamo un’analogia. Se una lista (List) è come una fila in mensa (ognuno ha la propria posizione, si può accedere per indice), allora una mappa (Map) è come un armadietto con scomparti: ogni scomparto ha un numero (chiave) e dentro c’è qualcosa di proprio (valore).

Interfaccia Map: operazioni di base

L’interfaccia Map dichiara i metodi fondamentali per lavorare con coppie chiave-valore:

Metodo Descrizione
put(K key, V value)
Aggiungere/sostituire il valore per una chiave
get(K key)
Ottenere il valore per una chiave
remove(K key)
Rimuovere la coppia per una chiave
containsKey(K key)
Verificare se esiste tale chiave
containsValue(V value)
Verificare se esiste tale valore
size()
Numero di coppie nella mappa
isEmpty()
Verificare se la mappa è vuota
clear()
Rimuovere tutte le coppie

I tipi K e V sono parametri generici: K (Key) è il tipo della chiave, V (Value) è il tipo del valore.

3. Classe HashMap: accesso rapido per chiave

Che cos’è HashMap?

HashMap è l’implementazione più diffusa dell’interfaccia Map. Fornisce accesso rapido ai valori per chiave.

Importante: HashMap non garantisce l’ordine di memorizzazione degli elementi! Se aggiungete le chiavi in un certo ordine, in iterazione potrebbero comparire in un altro.

Come creare una HashMap?

import java.util.HashMap;
import java.util.Map;

public class Example {
    public static void main(String[] args) {
        // Creiamo una mappa: chiave — String, valore — Integer
        Map<String, Integer> ages = new HashMap<>();

        // Aggiungiamo elementi
        ages.put("Vasya", 25);
        ages.put("Petya", 30);
        ages.put("Masha", 22);

        // Otteniamo un valore per chiave
        int vasyaAge = ages.get("Vasya");
        System.out.println("Età di Vasya: " + vasyaAge); // 25

        // Verifichiamo la presenza della chiave
        if (ages.containsKey("Masha")) {
            System.out.println("Masha è nell'elenco!");
        }

        // Rimuoviamo un elemento
        ages.remove("Petya");

        // Iteriamo su tutte le coppie chiave-valore
        for (String name : ages.keySet()) {
            System.out.println(name + ": " + ages.get(name));
        }
    }
}

Output:

Età di Vasya: 25
Masha è nell'elenco!
Vasya: 25
Masha: 22

Caratteristiche di HashMap

La cosa principale da ricordare: le chiavi in HashMap sono sempre uniche. Se inserite un nuovo elemento con una chiave già esistente, il valore precedente verrà sostituito con quello nuovo.

I valori possono ripetersi: diverse chiavi possono riferirsi allo stesso valore.

E un altro punto importante — l’ordine degli elementi. HashMap non si preoccupa dell’ordine di inserimento. In output le voci possono risultare rimescolate — è un comportamento normale.

4. Classe TreeMap: ordinamento per chiave

A differenza di HashMap, la classe TreeMap memorizza gli elementi in ordine ordinato per chiave.

Quando usare TreeMap?

Quando è importante che gli elementi siano in ordine crescente (o decrescente) delle chiavi. Ad esempio, se volete stampare una rubrica in ordine alfabetico.

Esempio:

import java.util.Map;
import java.util.TreeMap;

public class TreeMapExample {
    public static void main(String[] args) {
        Map<String, String> phoneBook = new TreeMap<>();

        phoneBook.put("Vasya", "+1-900-123-45-67");
        phoneBook.put("Masha", "+1-900-555-55-55");
        phoneBook.put("Petya", "+1-900-222-33-44");

        for (String name : phoneBook.keySet()) {
            System.out.println(name + ": " + phoneBook.get(name));
        }
    }
}

Output:

Masha: +1-900-555-55-55
Petya: +1-900-222-33-44
Vasya: +1-900-123-45-67

Da notare: le chiavi sono ordinate alfabeticamente.

5. Operazioni principali con Map

Aggiunta e sostituzione di elementi
Map<String, Integer> scores = new HashMap<>();
scores.put("Anna", 90);
scores.put("Ivan", 85);
scores.put("Anna", 95); // Sovrascriverà il valore per "Anna"
Ottenere un valore
Integer annaScore = scores.get("Anna"); // 95
Integer unknown = scores.get("Vasya");   // null, se tale chiave non esiste
Verifica della presenza di una chiave o di un valore
scores.containsKey("Ivan");    // true
scores.containsValue(85);      // true
Rimozione di una coppia per chiave
scores.remove("Ivan");
Dimensione della mappa e pulizia
int size = scores.size();
scores.clear(); // Rimuove tutti gli elementi

5. Iterare sugli elementi di Map

Map non è una lista, non ci sono indici. Ma si può iterare:

Per chiavi:

for (String key : scores.keySet()) {
    System.out.println("Chiave: " + key + ", Valore: " + scores.get(key));
}

Per valori:

for (Integer value : scores.values()) {
    System.out.println("Valore: " + value);
}

Per coppie chiave-valore (il modo migliore):

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

Quando usare HashMap e quando — TreeMap?

HashMap è l’opzione «predefinita» universale. Se l’ordine delle chiavi non è importante e la priorità è la velocità delle operazioni, quasi sempre si sceglie questa.

TreeMap è utile quando serve un ordine. Mantiene automaticamente le chiavi ordinate e consente di trovare rapidamente la chiave minima/massima o di lavorare con intervalli.

In sintesi: nel 90 % dei casi usiamo HashMap. Quando i dati devono essere subito «in ordine», utilizziamo TreeMap.

6. Esempi di utilizzo di Map

Esempio 1: Rubrica telefonica

Map<String, String> phoneBook = new HashMap<>();
phoneBook.put("Katya", "+1-999-111-22-33");
phoneBook.put("Oleg", "+1-999-222-33-44");
phoneBook.put("Katya", "+1-999-555-66-77"); // Il vecchio numero di Katya verrà sostituito dal nuovo

for (Map.Entry<String, String> entry : phoneBook.entrySet()) {
    System.out.println(entry.getKey() + ": " + entry.getValue());
}

Output:

Oleg: +1-999-222-33-44
Katya: +1-999-555-66-77

Esempio 2: Conteggio delle parole

Supponiamo di avere un elenco di parole e di voler sapere quante volte compare ciascuna parola:

import java.util.*;

public class WordCount {
    public static void main(String[] args) {
        List<String> words = Arrays.asList("mela", "banana", "mela", "pera", "banana", "mela");
        Map<String, Integer> counts = new HashMap<>();

        for (String word : words) {
            int oldCount = counts.getOrDefault(word, 0); // se la chiave non esiste — 0
            counts.put(word, oldCount + 1);
        }

        System.out.println(counts); // {pera=1, mela=3, banana=2}
    }
}

7. Errori tipici nell'uso di Map

Errore n. 1: confusione tra chiavi e valori. Spesso i principianti tentano di ottenere un valore per indice, come in una lista, o dimenticano che le chiavi devono essere uniche. In Map non ci sono indici — solo chiavi.

Errore n. 2: uso di chiavi e valori null. In HashMap è consentita una chiave null, ma in TreeMap — no (si avrà una NullPointerException). I valori possono essere null in entrambe le implementazioni, ma è raramente utile.

Errore n. 3: aspettarsi un ordine degli elementi in HashMap. HashMap non garantisce alcun ordine. Se serve un ordine — usate LinkedHashMap (mantiene l’ordine di inserimento) oppure TreeMap (ordina per chiave).

Errore n. 4: modificare la mappa durante l’iterazione. Se iterate su una Map e contemporaneamente aggiungete/rimuovete elementi — può verificarsi una ConcurrentModificationException. Per questi casi usate un iteratore con il metodo remove() o collezioni speciali.

Errore n. 5: confrontare chiavi e valori con == invece di equals. Map usa il metodo equals per confrontare le chiavi (e i valori). Se create le vostre classi da usare come chiavi, ricordate di sovrascrivere equals e hashCode.

1
Compito
JAVA 25 SELF, livello 26, lezione 2
Bloccato
Pianificatore intelligente di attività: giorni della settimana 🗓️
Pianificatore intelligente di attività: giorni della settimana 🗓️
1
Compito
JAVA 25 SELF, livello 26, lezione 2
Bloccato
Inventario dei frutti nel magazzino in ordine alfabetico 🍏🍌🍐
Inventario dei frutti nel magazzino in ordine alfabetico 🍏🍌🍐
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION