TreeSet în Java

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”.

Sintaxă
new TreeSet<>()
new TreeSet<>(Comparator<? super E> comparator)
new TreeSet<>(Collection<? extends E> c)

Ce face TreeSet

TreeSet păstrează elementele într-un arbore echilibrat (roșu-negru), deci sunt mereu în ordine: numerele crescător, textele alfabetic (după codurile caracterelor). Parcurgerea și afișarea respectă această ordine. Operațiile add, remove, contains sunt rapide (timp logaritmic), puțin mai lente decât la HashSet.

Pentru altă ordine, dai un Comparator la constructor: new TreeSet<>(Comparator.reverseOrder()) sau new TreeSet<>(String.CASE_INSENSITIVE_ORDER). Atenție: două elemente pe care comparatorul le consideră egale (rezultat 0) sunt tratate ca același element.

În plus față de un Set obișnuit, are metode de navigare: first/last, ceiling/floor, headSet/tailSet/subSet, descendingSet. Nu acceptă null.

Parametri

Parametru Descriere
comparator Regula de ordonare. Fără el, elementele trebuie să fie Comparable (String, Integer, LocalDate…).
c Colecția din care se copiază elementele.

Ce returnează

O mulțime sortată, modificabilă.

Exemple

Exemplul 1: Note unice, în ordine

import java.util.List;
import java.util.TreeSet;

public class Main {
    public static void main(String[] args) {
        TreeSet<Integer> note = new TreeSet<>(List.of(8, 10, 5, 8, 9, 5));
        System.out.println(note);
        System.out.println("Descrescător: " + note.descendingSet());
        System.out.println("Între 6 și 9: " + note.subSet(6, true, 9, true));
    }
}

Rezultat

[5, 8, 9, 10]
Descrescător: [10, 9, 8, 5]
Între 6 și 9: [8, 9]

Exemplul 2: Ordine personalizată cu Comparator

Cu CASE_INSENSITIVE_ORDER, „ana” și „Ana” sunt considerate același element, deci al doilea nu mai intră.

import java.util.Comparator;
import java.util.TreeSet;

public class Main {
    public static void main(String[] args) {
        TreeSet<String> dupaLungime = new TreeSet<>(Comparator.comparingInt(String::length).thenComparing(Comparator.naturalOrder()));
        dupaLungime.add("Constanța");
        dupaLungime.add("Iași");
        dupaLungime.add("Cluj");
        dupaLungime.add("Arad");
        System.out.println(dupaLungime);

        TreeSet<String> faraMajuscule = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
        faraMajuscule.add("Ana");
        System.out.println("add(\"ana\"): " + faraMajuscule.add("ana") + " " + faraMajuscule);
    }
}

Rezultat

[Arad, Cluj, Iași, Constanța]
add("ana"): false [Ana]

Exemplul 3: Clasament cu record și Comparator

import java.util.Comparator;
import java.util.TreeSet;

public class Main {
    record Elev(String nume, double medie) {}

    public static void main(String[] args) {
        TreeSet<Elev> clasament = new TreeSet<>(
                Comparator.comparingDouble(Elev::medie).reversed().thenComparing(Elev::nume));
        clasament.add(new Elev("Ana", 9.50));
        clasament.add(new Elev("Mihai", 8.75));
        clasament.add(new Elev("Ioana", 9.50));
        clasament.add(new Elev("Radu", 9.80));
        int loc = 1;
        for (Elev e : clasament) {
            System.out.println(loc++ + ". " + e.nume() + " " + e.medie());
        }
    }
}

Rezultat

1. Radu 9.8
2. Ana 9.5
3. Ioana 9.5
4. Mihai 8.75

Greșeli frecvente

  • Pui în TreeSet obiecte care nu sunt Comparable și nu dai un comparator. La primul add apare ClassCastException.
  • Comparatorul compară doar după un câmp (de exemplu media). Doi elevi cu aceeași medie sunt considerați egali și al doilea dispare. Adaugă un criteriu secundar cu thenComparing.
  • Adaugi null. TreeSet aruncă NullPointerException.

Comenzi înrudite

  • Set: Interfața pentru mulțimi: colecții fără duplicate, în care întrebi rapid dacă un element există.
  • HashSet: Mulțimea cea mai rapidă: add, remove și contains în timp aproape constant, dar fără o ordine garantată a elementelor.
  • TreeSet.first: first() returnează cel mai mic element al unui TreeSet, last() pe cel mai mare. Aruncă excepție dacă mulțimea e goală.
  • TreeSet.ceiling: ceiling(x) găsește cel mai mic element mai mare sau egal cu x; floor(x) cel mai mare element mai mic sau egal cu x.
  • TreeSet.headSet: headSet(x) returnează partea unui TreeSet cu elementele mai mici decât x, ca vedere legată de mulțimea originală.
  • TreeMap: Dicționar care ține cheile mereu sortate și oferă căutări de tip „prima cheie”, „cea mai apropiată cheie”, „intervalul de chei”.
  • Comparator: Interfața care spune cum se ordonează două obiecte: compare(a, b) returnează un număr negativ, zero sau pozitiv.