Set în Java

Interfața pentru mulțimi: colecții fără duplicate, în care întrebi rapid dacă un element există.

Sintaxă
import java.util.Set;
import java.util.HashSet;

Set<T> nume = new HashSet<>();
Set<T> nume = new TreeSet<>();
Set<T> nume = Set.of(v1, v2);

Ce face Set

Un Set (mulțime) ține fiecare valoare o singură dată. Dacă adaugi un element care există deja, add returnează false și mulțimea rămâne la fel. Elementele nu au poziții: nu există get(0).

Implementările principale: HashSet (cea mai rapidă, ordine nespecificată), LinkedHashSet (păstrează ordinea adăugării) și TreeSet (ține elementele sortate). Egalitatea se verifică cu equals (și hashCode la HashSet), iar la TreeSet cu compareTo.

Folosește un Set când vrei să elimini duplicatele, să verifici apartenența („a mai fost văzut acest email?”) sau să faci operații de mulțimi: reuniune (addAll), intersecție (retainAll), diferență (removeAll).

Parametri

Parametru Descriere
T Tipul elementelor.

Ce returnează

Un obiect care implementează Set.

Exemple

Exemplul 1: Eliminarea duplicatelor

Un LinkedHashSet păstrează prima apariție a fiecărui oraș, în ordinea din listă.

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

public class Main {
    public static void main(String[] args) {
        List<String> vizite = List.of("Iași", "Cluj", "Iași", "Sibiu", "Cluj", "Iași");
        Set<String> unice = new LinkedHashSet<>(vizite);
        System.out.println(vizite.size() + " vizite, " + unice.size() + " orașe: " + unice);
    }
}

Rezultat

6 vizite, 3 orașe: [Iași, Cluj, Sibiu]

Exemplul 2: Cele trei implementări, cu aceleași date

TreeSet sortează, LinkedHashSet păstrează ordinea adăugării. Pentru HashSet afișăm doar mărimea, pentru că ordinea lui nu este garantată.

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

public class Main {
    public static void main(String[] args) {
        List<String> nume = List.of("Radu", "Ana", "Elena", "Ana");
        Set<String> h = new HashSet<>(nume);
        Set<String> l = new LinkedHashSet<>(nume);
        Set<String> t = new TreeSet<>(nume);
        System.out.println("HashSet: " + h.size() + " elemente, conține Ana: " + h.contains("Ana"));
        System.out.println("LinkedHashSet: " + l);
        System.out.println("TreeSet: " + t);
    }
}

Rezultat

HashSet: 3 elemente, conține Ana: true
LinkedHashSet: [Radu, Ana, Elena]
TreeSet: [Ana, Elena, Radu]

Exemplul 3: Ai mai văzut acest cod?

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

public class Main {
    public static void main(String[] args) {
        Set<String> folosite = new HashSet<>();
        for (String cod : List.of("REDUCERE10", "VARA", "REDUCERE10", "TOAMNA")) {
            if (folosite.add(cod)) {
                System.out.println(cod + ": aplicat");
            } else {
                System.out.println(cod + ": a fost deja folosit");
            }
        }
    }
}

Rezultat

REDUCERE10: aplicat
VARA: aplicat
REDUCERE10: a fost deja folosit
TOAMNA: aplicat

Greșeli frecvente

  • Cauți set.get(i). O mulțime nu are poziții; parcurge-o cu for-each sau transform-o în listă.
  • Afișezi un HashSet și te bazezi pe ordinea afișată. Ordinea nu este garantată; folosește TreeSet sau LinkedHashSet.
  • Pui în HashSet obiecte ale unei clase proprii fără equals și hashCode. Două obiecte cu aceleași date sunt considerate diferite; folosește un record sau suprascrie ambele metode.

Comenzi înrudite

  • HashSet: Mulțimea cea mai rapidă: add, remove și contains în timp aproape constant, dar fără o ordine garantată a elementelor.
  • 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”.
  • LinkedHashMap: HashMap care ține minte ordinea în care au fost adăugate cheile; parcurgerea și afișarea respectă această ordine.
  • 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.of: Creează o mulțime nemodificabilă din valorile date (of) sau dintr-o colecție existentă (copyOf). Ordinea nu este garantată.
  • Collection: Interfața de bază pentru liste, mulțimi și cozi: metodele comune add, remove, contains, size și parcurgerea cu for-each.
  • List: Interfața pentru liste ordonate: elementele au poziții (0, 1, 2…), se pot repeta și se pot citi după index.