HashMap în Java

Dicționarul cel mai rapid: put, get și remove în timp aproape constant, dar fără ordine garantată a cheilor.

Sintaxă
new HashMap<>()
new HashMap<>(int capacitateInitiala)
new HashMap<>(Map<? extends K, ? extends V> m)

Ce face HashMap

HashMap ține perechile într-un tabel de dispersie: din hashCode() al cheii calculează locul în care pune perechea. De aceea put, get, containsKey și remove sunt foarte rapide, indiferent de mărime. Este alegerea implicită când ai nevoie de un dicționar.

Ordinea cheilor la parcurgere nu este garantată și se poate schimba când map-ul crește. Dacă vrei ordinea adăugării, folosește LinkedHashMap; dacă vrei cheile sortate, TreeMap. Pentru afișare ordonată poți copia: new TreeMap<>(hashMap).

Cheile trebuie să aibă equals și hashCode corecte (String, numerele, enum-urile și record-urile le au). Sunt permise o cheie null și valori null. HashMap nu este sigur între fire de execuție; pentru asta există ConcurrentHashMap.

Parametri

Parametru Descriere
capacitateInitiala Mărimea inițială a tabelului; utilă doar pentru map-uri foarte mari.
m Un map din care se copiază perechile.

Ce returnează

Un dicționar nou, modificabil.

Exemple

Exemplul 1: Prețurile din meniu

Citim după cheie din HashMap; pentru afișarea întregului meniu copiem în TreeMap, ca ordinea să fie alfabetică.

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

public class Main {
    public static void main(String[] args) {
        Map<String, Double> meniu = new HashMap<>();
        meniu.put("ciorbă", 18.5);
        meniu.put("sarmale", 32.0);
        meniu.put("papanași", 22.0);

        double total = meniu.get("ciorbă") + meniu.get("papanași");
        System.out.println("Nota: " + total + " lei");
        System.out.println("Meniu: " + new TreeMap<>(meniu));
    }
}

Rezultat

Nota: 40.5 lei
Meniu: {ciorbă=18.5, papanași=22.0, sarmale=32.0}

Exemplul 2: Record ca cheie

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

public class Main {
    record Loc(int rand, int scaun) {}

    public static void main(String[] args) {
        Map<Loc, String> rezervari = new HashMap<>();
        rezervari.put(new Loc(5, 12), "Ana");
        rezervari.put(new Loc(5, 13), "Radu");
        System.out.println("Locul 5/12: " + rezervari.get(new Loc(5, 12)));
        System.out.println("Locul 7/1 liber? " + !rezervari.containsKey(new Loc(7, 1)));
    }
}

Rezultat

Locul 5/12: Ana
Locul 7/1 liber? true

Exemplul 3: Gruparea elevilor pe clase

computeIfAbsent creează lista clasei la prima apariție. La afișare sortăm cheile ca text, deci „10B” vine înaintea lui „9A”.

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;

public class Main {
    public static void main(String[] args) {
        String[][] elevi = {{"Ana", "9A"}, {"Radu", "10B"}, {"Ioana", "9A"}, {"Mihai", "10B"}, {"Elena", "11C"}};
        Map<String, List<String>> peClase = new HashMap<>();
        for (String[] e : elevi) {
            peClase.computeIfAbsent(e[1], k -> new ArrayList<>()).add(e[0]);
        }
        for (String clasa : new TreeSet<>(peClase.keySet())) {
            System.out.println(clasa + ": " + peClase.get(clasa));
        }
    }
}

Rezultat

10B: [Radu, Mihai]
11C: [Elena]
9A: [Ana, Ioana]

Greșeli frecvente

  • Afișezi un HashMap și presupui că ordinea rămâne aceeași. Nu este garantată.
  • Folosești ca cheie o clasă proprie fără equals/hashCode. get cu un obiect nou cu aceleași date returnează null; folosește un record.
  • Modifici același HashMap din mai multe fire de execuție. Datele se pot corupe; folosește ConcurrentHashMap.

Comenzi înrudite

  • Map: Interfața pentru dicționare: perechi cheie → valoare, în care găsești rapid valoarea după cheie. Cheile sunt unice.
  • TreeMap: Dicționar care ține cheile mereu sortate și oferă căutări de tip „prima cheie”, „cea mai apropiată cheie”, „intervalul de chei”.
  • LinkedHashMap: HashMap care ține minte ordinea în care au fost adăugate cheile; parcurgerea și afișarea respectă această ordine.
  • HashSet: Mulțimea cea mai rapidă: add, remove și contains în timp aproape constant, dar fără o ordine garantată a elementelor.
  • Map.put: put adaugă o pereche cheie → valoare sau înlocuiește valoarea unei chei existente; putAll copiază toate perechile altui map.
  • Map.get: get returnează valoarea unei chei sau null dacă lipsește; getOrDefault returnează o valoare de rezervă în loc de null.