🌳 TreeSet em Java

O TreeSet é uma implementação da interface Set baseada em uma árvore vermelha-preta (Red-Black Tree). Ele mantém os elementos ordenados de forma natural (via Comparable) ou por um Comparator customizado.

🧠 Características principais do TreeSet

  • Ordenado: mantém os elementos em ordem crescente por padrão.
  • Não permite elementos duplicados.
  • Não permite null se for comparado (inserido após outros elementos).
  • Não é thread-safe.
  • Complexidade das operações básicas é O(log n).

🔧 Principais métodos do TreeSet com exemplos

✅ Exemplo básico de uso

TreeSet<Integer> numeros = new TreeSet<>();
numeros.add(5);
numeros.add(1);
numeros.add(3);
System.out.println(numeros);

Comentário:

  • Linha 1: Cria um TreeSet de Integer, que implementa Comparable.
  • Linha 2-4: Elementos são adicionados fora de ordem.
  • Linha 5: A saída será [1, 3, 5], pois TreeSet ordena automaticamente.

✅ Métodos mais usados

import static java.lang.System.out;
TreeSet<String> nomes = new TreeSet<>();
nomes.add("João");
nomes.add("Ana");
nomes.add("Carlos");

out.println(nomes.first());
out.println(nomes.last());
out.println(nomes.lower("Carlos"));
out.println(nomes.higher("Carlos"));
out.println(nomes.headSet("Carlos"));
out.println(nomes.tailSet("Carlos"));
out.println(nomes.subSet("Ana", "João"));

Comentários:

  • Linha 1: Cria um TreeSet com elementos do tipo String.
  • Linhas 7-13: Mostra os métodos:

first() – menor elemento
last() – maior elemento
lower(e) – menor que e
higher(e) – maior que e
headSet(e) – menores que e (exclusivo)
tailSet(e) – maiores ou iguais a e
subSet(a, b) – entre a (inclusive) e b (exclusivo)

🔢 TreeSet<Integer> com 10 números

import java.util.*;
import static java.lang.System.out;

public class TreeSetNumeros {
  public static void main(String[] args) {
    TreeSet<Integer> numeros = new TreeSet<>();
    numeros.add(10);
    numeros.add(5);
    numeros.add(8);
    numeros.add(3);
    numeros.add(1);
    numeros.add(7);
    numeros.add(6);
    numeros.add(2);
    numeros.add(9);
    numeros.add(4);

    out.println(numeros);
    out.println(numeros.first());
    out.println(numeros.last());
    out.println(numeros.higher(5));
    out.println(numeros.lower(5));
    out.println(numeros.headSet(5));
    out.println(numeros.tailSet(5));
    out.println(numeros.subSet(3, 8));
    out.println(numeros.pollFirst());
    out.println(numeros);
  }
}

Comentários:

  • Linha 7–16: Adiciona 10 números fora de ordem.
  • Linha 18: TreeSet ordena automaticamente: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  • Linha 19: first()1 (obtém o menor/primeiro elemento)
  • Linha 20: last()10
  • Linha 21: higher(5)6 (busca o próximo que seja maior do que o da busca)
  • Linha 22: lower(5)4
  • Linha 23: headSet(5)[1, 2, 3, 4]
  • Linha 24: tailSet(5)[5, 6, 7, 8, 9, 10]
  • Linha 25: subSet(3, 8)[3, 4, 5, 6, 7] (Subconjunto entre 3 (inclusive) e 8 (exclusive))
  • Linha 26: pollFirst() → remove e retorna 1
  • Linha 26: TreeSet atualizado → [2, 3, 4, 5, 6, 7, 8, 9, 10]

🔤 TreeSet<String> com nomes

import java.util.*;
import static java.lang.System.out;

public class TreeSetNomes {
  public static void main(String[] args) {
    TreeSet<String> nomes = new TreeSet<>();
    nomes.add("Carlos");
    nomes.add("Ana");
    nomes.add("Bruno");
    nomes.add("Daniela");
    nomes.add("Eduardo");

    out.println(nomes);// [Ana, Bruno, Carlos, Daniela, Eduardo]
    out.println(nomes.first()); // Ana
    out.println(nomes.last()); // Eduardo
    out.println(nomes.higher("Bruno"));// Carlos
    out.println(nomes.lower("Bruno"));// Ana
    out.println(nomes.headSet("Daniela"));//[Ana, Bruno, Carlos]
    out.println(nomes.tailSet("Daniela"));//[Daniela, Eduardo]
  }
}

Comentários:

  • Linha 7–11: Adiciona nomes fora de ordem.
  • Linha 13: TreeSet ordenado automaticamente: [Ana, Bruno, Carlos, Daniela, Eduardo]
  • Linha 14: first()Ana
  • Linha 15: last()Eduardo
  • Linha 16: higher("Bruno")Carlos
  • Linha 17: lower("Bruno")Ana
  • Linha 18: headSet("Daniela")[Ana, Bruno, Carlos]
  • Linha 19: tailSet("Daniela")[Daniela, Eduardo]

⚖️ Comparable (ordem natural personalizada)

import java.util.*;

class Produto implements Comparable<Produto> {
  String nome;
  double preco;

  Produto(String nome, double preco) {
    this.nome = nome;
    this.preco = preco;
  }

  public int compareTo(Produto outro) {
    return this.nome.compareTo(outro.nome);
  }

  public String toString() {
    return nome + " - R$" + preco;
  }
}

public class TreeSetComparable {
  public static void main(String[] args) {
    TreeSet<Produto> produtos = new TreeSet<>();
    produtos.add(new Produto("Arroz", 10.5));
    produtos.add(new Produto("Feijão", 7.0));
    produtos.add(new Produto("Macarrão", 5.0));
    produtos.add(new Produto("Batata", 4.0));

    for (Produto p : produtos) {
      System.out.println(p);
    }
  }
}

Comentários:

  • Linha 3–15: A classe Produto implementa Comparable, ordenando por nome.
  • TreeSet ordena os produtos em ordem alfabética: Arroz, Batata, Feijão, Macarrão.

🔄 Comparator (ordenação por preço)

import java.util.*;

class Produto {
  String nome;
  double preco;

  Produto(String nome, double preco) {
    this.nome = nome;
    this.preco = preco;
  }

  public String toString() {
    return nome + " - R$" + preco;
  }
}

public class TreeSetComparator {
  public static void main(String[] args) {
    TreeSet<Produto> produtos = 
new TreeSet<>(Comparator.comparingDouble(p -> p.preco));
    produtos.add(new Produto("Arroz", 10.5));
    produtos.add(new Produto("Feijão", 7.0));
    produtos.add(new Produto("Macarrão", 5.0));
    produtos.add(new Produto("Batata", 4.0));

    for (Produto p : produtos) {
      System.out.println(p);
    }
  }
}

Comentários:

  • Linha 15: TreeSet é criado com Comparator para ordenar por preco.
  • A saída será:

Batata - R$4.0
Macarrão - R$5.0
Feijão - R$7.0
Arroz - R$10.5

❌ Exemplo incorreto: usar null com elementos comparáveis

TreeSet<String> ts = new TreeSet<>();
ts.add(null);

Lança NullPointerException, pois o TreeSet precisa comparar os elementos.

✅ Usar Comparator customizado
Ordenação reversa usando lambda:

TreeSet<String> nomes = new TreeSet<>((a, b) -> b.compareTo(a));
nomes.add("João");
nomes.add("Ana");
nomes.add("Carlos");
System.out.println(nomes);

🛠️ Dicas de prova e pegadinhas

  • Usar null em TreeSet com outros elementos dá exceção.
  • TreeSet não aceita duplicatas. add() retorna false se já existir.
  • Sempre lembrar que é ordenado, diferentemente do HashSet.
  • Iterações ocorrem na ordem ordenada automaticamente.

🧪 Quiz sobre TreeSet

🧩 Clique na pergunta para ver resposta, tente resolver antes.
1️⃣ Qual alternativa cria corretamente um TreeSet que armazena inteiros?

Resposta:B

A) TreeSet<int> set = new TreeSet<>();
B) Set<Integer> set = new TreeSet<>();
C) Set<int> set = new TreeSet<>();
D) TreeSet<Integer> set = new HashSet<>();

2️⃣ O que acontece se você tentar adicionar null a um TreeSet<String>?

Resposta:D

A) Será adicionado sem problemas
B) A lista ficará ordenada com null na primeira posição
C) Ocorrerá erro de compilação
D) Lançará NullPointerException em tempo de execução

3️⃣ Qual é o resultado esperado?

Resposta: C
Como ele ordena em ordem natural o 5 vem primeiro na ordenação então first = 5.

Set<Integer> set = new TreeSet<>();
set.add(10);
set.add(5);
set.add(20);
System.out.println(set.first());

A) 20
B) 10
C) 5
D) Lança exceção

4️⃣O que imprime o código abaixo?

B – Elementos são ordenados: [1, 2, 3]

TreeSet<Integer> set = new TreeSet<>();
set.add(3);
set.add(1);
set.add(2);
System.out.println(set);

A) [3, 1, 2]
B) [1, 2, 3]
C) Ordem indefinida
D) Compila mas lança exceção

5️⃣ O que acontece ao executar?

CNullPointerException, pois null não pode ser comparado

TreeSet<String> set = new TreeSet<>();
set.add("A");
set.add(null);

A) Imprime [A, null]
B) Imprime [null, A]
C) Lança NullPointerException
D) Compila e não imprime nada

6️⃣ Qual o resultado de set.first()?

Afirst() retorna o menor elemento, que é “A”

TreeSet<String> set = new TreeSet<>();
set.add("C");
set.add("A");
set.add("B");
System.out.println(set.first());

A) A
B) B
C) C
D) null

7️⃣ Qual das alternativas remove o menor elemento?

BpollFirst() remove e retorna o menor elemento

A) set.first()
B) set.pollFirst()
C) set.lower()
D) set.removeFirst()

8️⃣ O método tailSet("C") em um TreeSet com [“A”, “B”, “C”, “D”] retorna:

AtailSet("C") retorna elementos >= “C”

A) [“C”, “D”]
B) [“B”, “C”, “D”]
C) [“D”]
D) [“A”, “B”, “C”]

9️⃣ Qual alternativa é verdadeira sobre TreeSet?

DTreeSet é ordenado naturalmente ou por Comparator

A) Permite elementos duplicados
B) Permite múltiplos null
C) Mantém ordem de inserção
D) É ordenado naturalmente ou por Comparator

🔟 O que imprime?

Chigher(10) retorna o próximo maior: 20

TreeSet<Integer> set = new TreeSet<>();
set.add(10);
set.add(5);
set.add(20);
System.out.println(set.higher(10));

A) 5
B) 10
C) 20
D) null

1️⃣1️⃣ O que imprime?

CsubSet(a, b) inclui a, exclui b: [a]

TreeSet<String> set = new TreeSet<>();
set.add("a");
set.add("b");
System.out.println(set.subSet("a", "b"));
1️⃣2️⃣ Qual construtor cria um TreeSet com ordem decrescente?

BCollections.reverseOrder() cria ordenação reversa

A) new TreeSet<>()
B) new TreeSet(Collections.reverseOrder())
C) new TreeSet(null)
D) new TreeSet("reverse")

1️⃣3️⃣ Qual é o tipo da interface que TreeSet implementa?

CTreeSet implementa Set, que estende Collection

A) Map
B) List
C) Set
D) Collection

📌 Resumo

  • TreeSet é um Set ordenado baseado em árvore.
  • Ordena os elementos naturalmente (Comparable) ou com Comparator.
  • Não permite elementos duplicados.
  • Não aceita null após elementos não nulos.
  • Possui métodos úteis como first(), last(), higher(), lower(), headSet(), tailSet(), subSet(), pollFirst(), etc.

Deixe um comentário