Java TreeMap: Domine Mapas Ordenados com Exemplos Práticos
Java TreeMap
Explore a classe TreeMap do Java – uma implementação poderosa de mapa naturalmente ordenado – com exemplos claros, operações principais e técnicas avançadas de navegação.
A classe TreeMap é parte do Java Collections Framework e fornece uma implementação de árvore rubro-negra que mantém suas entradas ordenadas de acordo com a ordenação natural das chaves ou um Comparator personalizado. Ela implementa a interface NavigableMap, que adiciona métodos convenientes para percorrer e consultar o mapa.
Criando um TreeMap
Antes de usar um TreeMap, importe o pacote:
import java.util.TreeMap;
Então crie uma instância:
TreeMap<Chave, Valor> numeros = new TreeMap<>();
Por padrão, chaves são ordenadas em ordem natural crescente. Se você precisar de uma ordem personalizada, passe um Comparator para o construtor.
- Chave – identificador único para cada entrada.
- Valor – dados associados à chave.
Visão Geral dos Métodos do TreeMap
A classe oferece um rico conjunto de operações. Abaixo estão categorias principais com snippets de código.
Inserindo Elementos
put()– adiciona ou substitui um par chave/valor.putAll()– mescla outro mapa neste.putIfAbsent()– insere apenas se a chave estiver faltando.
Exemplo:
import java.util.TreeMap;
class Main {
public static void main(String[] args) {
TreeMap<String, Integer> numerosPares = new TreeMap<>();
numerosPares.put("Dois", 2);
numerosPares.put("Quatro", 4);
numerosPares.putIfAbsent("Seis", 6);
System.out.println("TreeMap de números pares: " + numerosPares);
TreeMap<String, Integer> numeros = new TreeMap<>();
numeros.put("Um", 1);
numeros.putAll(numerosPares);
System.out.println("TreeMap de números: " + numeros);
}
}
Saída
TreeMap de números pares: {Quatro=4, Seis=6, Dois=2} TreeMap de números: {Quatro=4, Um=1, Seis=6, Dois=2}
Acessando Elementos
Usando Visualizações de Coleção
entrySet()– retorna todos os pares chave/valor.keySet()– retorna todas as chaves.values()– retorna todos os valores.
Exemplo:
import java.util.TreeMap;
class Main {
public static void main(String[] args) {
TreeMap<String, Integer> numeros = new TreeMap<>();
numeros.put("Um", 1);
numeros.put("Dois", 2);
numeros.put("Três", 3);
System.out.println("TreeMap: " + numeros);
System.out.println("Mapeamentos Chave/Valor: " + numeros.entrySet());
System.out.println("Chaves: " + numeros.keySet());
System.out.println("Valores: " + numeros.values());
}
}
Saída
TreeMap: {Um=1, Três=3, Dois=2} Mapeamentos Chave/Valor: [Um=1, Três=3, Dois=2] Chaves: [Um, Três, Dois] Valores: [1, 3, 2]
Recuperando Valores
get()– retorna o valor para uma chave ounullse ausente.getOrDefault()– retorna um padrão se a chave estiver faltando.
Exemplo:
import java.util.TreeMap;
class Main {
public static void main(String[] args) {
TreeMap<String, Integer> numeros = new TreeMap<>();
numeros.put("Um", 1);
numeros.put("Dois", 2);
numeros.put("Três", 3);
System.out.println("TreeMap: " + numeros);
int valor1 = numeros.get("Três");
System.out.println("Usando get(): " + valor1);
int valor2 = numeros.getOrDefault("Cinco", 5);
System.out.println("Usando getOrDefault(): " + valor2);
}
}
Saída
TreeMap: {Um=1, Três=3, Dois=2} Usando get(): 3 Usando getOrDefault(): 5
Removendo Entradas
remove(chave)– deleta a entrada e retorna seu valor.remove(chave, valor)– deleta apenas se a chave mapear para o valor especificado.
Exemplo:
import java.util.TreeMap;
class Main {
public static void main(String[] args) {
TreeMap<String, Integer> numeros = new TreeMap<>();
numeros.put("Um", 1);
numeros.put("Dois", 2);
numeros.put("Três", 3);
System.out.println("TreeMap: " + numeros);
int removido = numeros.remove("Dois");
System.out.println("Valor removido: " + removido);
boolean removidoPar = numeros.remove("Três", 3);
System.out.println("A entrada {Três=3} foi removida? " + removidoPar);
System.out.println("TreeMap Atualizado: " + numeros);
}
}
Saída
TreeMap: {Um=1, Três=3, Dois=2} Valor removido: 2 A entrada {Três=3} foi removida? true TreeMap Atualizado: {Um=1}
Substituindo Valores
replace(chave, valor)– atualiza o valor para uma chave.replace(chave, antigo, novo)– atualiza apenas se o valor atual corresponder aantigo.replaceAll(funcao)– aplica uma função a cada entrada.
Exemplo:
import java.util.TreeMap;
class Main {
public static void main(String[] args) {
TreeMap<String, Integer> numeros = new TreeMap<>();
numeros.put("Primeiro", 1);
numeros.put("Segundo", 2);
numeros.put("Terceiro", 3);
System.out.println("TreeMap Original: " + numeros);
numeros.replace("Segundo", 22);
numeros.replace("Terceiro", 3, 33);
System.out.println("Após replace(): " + numeros);
numeros.replaceAll((k, v) -> v + 2);
System.out.println("Após replaceAll(): " + numeros);
}
}
Saída
TreeMap Original: {Primeiro=1, Segundo=2, Terceiro=3} Após replace(): {Primeiro=1, Segundo=22, Terceiro=33} Após replaceAll(): {Primeiro=3, Segundo=24, Terceiro=35}
Métodos de Navegação
Como TreeMap implementa NavigableMap, oferece métodos para consultar a estrutura eficientemente.
Primeiros e Últimos Elementos
firstKey()– primeira chave em ordem.firstEntry()– entrada para a primeira chave.lastKey()– última chave.lastEntry()– entrada para a última chave.
Exemplo:
import java.util.TreeMap;
class Main {
public static void main(String[] args) {
TreeMap<String, Integer> numeros = new TreeMap<>();
numeros.put("Primeiro", 1);
numeros.put("Segundo", 2);
numeros.put("Terceiro", 3);
System.out.println("TreeMap: " + numeros);
System.out.println("Primeira Chave: " + numeros.firstKey());
System.out.println("Última Chave: " + numeros.lastKey());
System.out.println("Primeira Entrada: " + numeros.firstEntry());
System.out.println("Última Entrada: " + numeros.lastEntry());
}
}
Saída
TreeMap: {Primeiro=1, Segundo=2, Terceiro=3} Primeira Chave: Primeiro Última Chave: Terceiro Primeira Entrada: Primeiro=1 Última Entrada: Terceiro=3
Ceiling, Floor, Higher e Lower
Esses métodos retornam chaves ou entradas relativas a uma chave dada, facilitando consultas de intervalo.
higherKey(),higherEntry()– próxima chave/entrada maior.lowerKey(),lowerEntry()– chave/entrada anterior menor.ceilingKey(),ceilingEntry()– menor chave/entrada ≥ chave dada.floorKey(),floorEntry()– maior chave/entrada ≤ chave dada.
Exemplo:
import java.util.TreeMap;
class Main {
public static void main(String[] args) {
TreeMap<String, Integer> numeros = new TreeMap<>();
numeros.put("Primeiro", 1);
numeros.put("Segundo", 5);
numeros.put("Terceiro", 4);
numeros.put("Quarto", 6);
System.out.println("TreeMap: " + numeros);
System.out.println("higherKey('Quarto'): " + numeros.higherKey("Quarto"));
System.out.println("higherEntry('Quarto'): " + numeros.higherEntry("Quarto"));
System.out.println("lowerKey('Quarto'): " + numeros.lowerKey("Quarto"));
System.out.println("lowerEntry('Quarto'): " + numeros.lowerEntry("Quarto"));
System.out.println("ceilingKey('Quarto'): " + numeros.ceilingKey("Quarto"));
System.out.println("ceilingEntry('Quarto'): " + numeros.ceilingEntry("Quarto"));
System.out.println("floorKey('Quarto'): " + numeros.floorKey("Quarto"));
System.out.println("floorEntry('Quarto'): " + numeros.floorEntry("Quarto"));
}
}
Saída
TreeMap: {Primeiro=1, Quarto=6, Segundo=5, Terceiro=4} higherKey('Quarto'): Segundo higherEntry('Quarto'): Segundo=5 lowerKey('Quarto'): Primeiro lowerEntry('Quarto'): Primeiro=1 ceilingKey('Quarto'): Quarto ceilingEntry('Quarto'): Quarto=6 floorKey('Quarto'): Quarto floorEntry('Quarto'): Quarto=6
Polling e Intervalos
pollFirstEntry() e pollLastEntry() removem e retornam as primeiras/últimas entradas, respectivamente.
import java.util.TreeMap;
class Main {
public static void main(String[] args) {
TreeMap<String, Integer> numeros = new TreeMap<>();
numeros.put("Primeiro", 1);
numeros.put("Segundo", 2);
numeros.put("Terceiro", 3);
System.out.println("TreeMap: " + numeros);
System.out.println("pollFirstEntry(): " + numeros.pollFirstEntry());
System.out.println("pollLastEntry(): " + numeros.pollLastEntry());
System.out.println("TreeMap Atualizado: " + numeros);
}
}
Saída
TreeMap: {Primeiro=1, Segundo=2, Terceiro=3} pollFirstEntry(): Primeiro=1 pollLastEntry(): Terceiro=3 TreeMap Atualizado: {Segundo=2}
headMap, tailMap, subMap
Esses métodos fornecem visões sobre intervalos de chaves específicos.
headMap(ateChave, inclusivo)– chaves < ateChave (ou ≤ se inclusivo).tailMap(deChave, inclusivo)– chaves ≥ deChave (ou > se exclusivo).subMap(deChave, deInclusivo, ateChave, ateInclusivo)– chaves entre os dois limites.
Exemplo:
import java.util.TreeMap;
class Main {
public static void main(String[] args) {
TreeMap<String, Integer> numeros = new TreeMap<>();
numeros.put("Primeiro", 1);
numeros.put("Segundo", 2);
numeros.put("Terceiro", 3);
numeros.put("Quarto", 4);
System.out.println("TreeMap: " + numeros);
System.out.println("headMap('Quarto'): " + numeros.headMap("Quarto"));
System.out.println("headMap('Quarto', true): " + numeros.headMap("Quarto", true));
System.out.println("tailMap('Segundo'): " + numeros.tailMap("Segundo"));
System.out.println("tailMap('Segundo', false): " + numeros.tailMap("Segundo", false));
System.out.println("subMap('Quarto', true, 'Terceiro', false): " + numeros.subMap("Quarto", true, "Terceiro", false));
}
}
Saída
TreeMap: {Primeiro=1, Quarto=4, Segundo=2, Terceiro=3} headMap('Quarto'): {Primeiro=1} headMap('Quarto', true): {Primeiro=1, Quarto=4} tailMap('Segundo'): {Segundo=2, Terceiro=3, Quarto=4} tailMap('Segundo', false): {Terceiro=3, Quarto=4} subMap('Quarto', true, 'Terceiro', false): {Quarto=4, Segundo=2}
Métodos Utilitários Adicionais
| Método | Descrição |
|---|---|
clone() | Cria uma cópia rasa do mapa. |
containsKey() | Verifica presença de uma chave. |
containsValue() | Verifica um valor específico. |
size() | Retorna o número de entradas. |
clear() | Remove todas as entradas. |
Ordenação Personalizada de Chaves com Comparator
Para ordenar chaves diferentemente — como ordem reversa ou strings case-insensitive — implemente Comparator e passe para o construtor do TreeMap.
import java.util.TreeMap;
import java.util.Comparator;
class Main {
public static void main(String[] args) {
TreeMap<String, Integer> numeros = new TreeMap<>(new ComparadorPersonalizado());
numeros.put("Primeiro", 1);
numeros.put("Segundo", 2);
numeros.put("Terceiro", 3);
numeros.put("Quarto", 4);
System.out.println("TreeMap: " + numeros);
}
static class ComparadorPersonalizado implements Comparator<String> {
@Override
public int compare(String a, String b) {
// Ordem natural reversa
return a.compareTo(b) * -1;
}
}
}
Saída
TreeMap: {Terceiro=3, Segundo=2, Quarto=4, Primeiro=1}
Para mais sobre Comparator, veja a documentação oficial do Java.
Java
- Dominando Operadores Java: Tipos, Sintaxe e Exemplos Práticos
- Comentários em Java: Tipos, Uso e Boas Práticas
- Dominando o Loop for Aprimorado em Java: Sintaxe, Exemplos e Boas Práticas
- Dominando Strings em Java: Criação, Métodos e Boas Práticas
- Dominando Interfaces em Java: Conceitos, Implementação e Boas Práticas
- Dominando Classes Internas Anônimas em Java: Definição, Sintaxe e Exemplos Práticos
- Dominando Try-With-Resources em Java: Gerenciamento Automático de Recursos Explicado
- Anotações em Java Explicadas: Tipos, Posicionamento e Exemplos Práticos
- Asserções em Java: Guia Prático para Detectar Bugs e Garantir Confiabilidade do Código
- Dominando Algoritmos de Coleção Java: Ordenação, Embaralhamento e Mais