HashSet în Java

Mulțimea cea mai rapidă: add, remove și contains în timp aproape constant, dar fără o ordine garantată a elementelor.

Sintaxă
new HashSet<>()
new HashSet<>(Collection<? extends E> c)
new HashSet<>(int capacitateInitiala)

new LinkedHashSet<>()   // păstrează ordinea adăugării

Ce face HashSet

HashSet ține elementele într-un tabel de dispersie (hash table). Pentru fiecare element calculează hashCode() și îl pune într-o „găleată”. Din această cauză, add, remove și contains sunt foarte rapide chiar și pentru milioane de elemente.

Prețul vitezei: ordinea elementelor la parcurgere sau la afișare nu este garantată și se poate schimba când adaugi elemente. Dacă ai nevoie de ordine, folosește LinkedHashSet (ordinea adăugării, aproape la fel de rapid) sau TreeSet (ordine sortată).

Elementele trebuie să aibă equals și hashCode corecte. String, Integer și record-urile le au deja. Este permis și un singur element null.

Parametri

Parametru Descriere
c Colecția din care se copiază elementele (duplicatele dispar).
capacitateInitiala Mărimea inițială a tabelului intern; utilă doar pentru mulțimi foarte mari.

Ce returnează

O mulțime nouă, modificabilă.

Exemple

Exemplul 1: Cuvinte distincte dintr-un text

Numărăm cu HashSet, apoi copiem într-un TreeSet ca să afișăm în ordine alfabetică.

import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;

public class Main {
    public static void main(String[] args) {
        String text = "ana are mere și ana are pere și mere";
        Set<String> cuvinte = new HashSet<>();
        for (String c : text.split(" ")) {
            cuvinte.add(c);
        }
        System.out.println("Cuvinte distincte: " + cuvinte.size());
        System.out.println("Alfabetic: " + new TreeSet<>(cuvinte));
    }
}

Rezultat

Cuvinte distincte: 5
Alfabetic: [ana, are, mere, pere, și]

Exemplul 2: Un record în HashSet

Record-ul are automat equals și hashCode, deci două obiecte cu aceleași date sunt același element.

import java.util.HashSet;
import java.util.Set;

public class Main {
    record Loc(String oras, int cod) {}

    public static void main(String[] args) {
        Set<Loc> locuri = new HashSet<>();
        locuri.add(new Loc("Iași", 700001));
        locuri.add(new Loc("Cluj", 400001));
        boolean nou = locuri.add(new Loc("Iași", 700001));
        System.out.println("Adăugat din nou? " + nou);
        System.out.println("Mărime: " + locuri.size());
        System.out.println("Conține Cluj? " + locuri.contains(new Loc("Cluj", 400001)));
    }
}

Rezultat

Adăugat din nou? false
Mărime: 2
Conține Cluj? true

Exemplul 3: LinkedHashSet pentru ordinea adăugării

import java.util.LinkedHashSet;
import java.util.Set;

public class Main {
    public static void main(String[] args) {
        Set<String> istoric = new LinkedHashSet<>();
        for (String pagina : new String[] {"acasă", "produse", "coș", "produse", "plată"}) {
            istoric.add(pagina);
        }
        System.out.println("Pagini vizitate: " + istoric);
    }
}

Rezultat

Pagini vizitate: [acasă, produse, coș, plată]

Greșeli frecvente

  • Te bazezi pe ordinea în care HashSet afișează elementele. Poate fi diferită pe alt JDK sau după alte adăugări.
  • Modifici un obiect după ce l-ai pus în HashSet, schimbând câmpurile folosite de hashCode. Mulțimea nu îl mai găsește cu contains.

Comenzi înrudite

  • Set: Interfața pentru mulțimi: colecții fără duplicate, în care întrebi rapid dacă un element există.
  • TreeSet: Mulțime care ține elementele mereu sortate (crescător sau după un Comparator) și oferă căutări de tip „cel mai mic”, „cel mai apropiat”.
  • HashMap: Dicționarul cel mai rapid: put, get și remove în timp aproape constant, dar fără ordine garantată a cheilor.
  • Set.add: Adaugă un element în mulțime doar dacă nu există deja; returnează true dacă a fost adăugat. addAll face reuniunea.
  • Set.contains: contains verifică rapid dacă un element este în mulțime; containsAll verifică dacă sunt toate elementele altei colecții.
  • Set.equals: Două mulțimi sunt egale dacă au exact aceleași elemente, indiferent de ordine sau de implementare (HashSet, TreeSet).