0Pricing
Java Academy · Aula

Ordenação Personalizada em Coleções Tree

Forneça um Comparator a TreeMap ou TreeSet para definir ordens de classificação específicas do domínio.

Ordenação Personalizada em Coleções Tree é uma aula grátis de Java Academy no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Java Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Java Academy inclui 4 aulas no total.

Por que usar uma ordenação personalizada?

As coleções baseadas em árvores (TreeMap, TreeSet) usam a ordenação natural por padrão. Quando os objetos do seu domínio não têm uma ordem natural ou quando você precisa de uma ordenação diferente, forneça um Comparator no momento da construção.

Comparator na construção de TreeMap

Passe um comparador para ordenar as chaves segundo uma regra personalizada — por exemplo, em ordem alfabética inversa:

import java.util.*;

TreeMap<String, Integer> map = new TreeMap<>(Comparator.reverseOrder());
map.put("banana", 2);
map.put("apple", 1);
map.put("cherry", 3);

map.forEach((k,v) -> System.out.println(k)); // cherry, banana, apple

Comparator na construção de TreeSet

Forneça um comparador à TreeSet para controlar a ordem de classificação independentemente da ordenação natural do elemento:

TreeSet<String> byLength = new TreeSet<>(
    Comparator.comparingInt(String::length)
              .thenComparing(Comparator.naturalOrder())
);
byLength.addAll(List.of("fig","apple","kiwi","date","banana"));

for (String s : byLength) System.out.print(s + " ");
// fig date kiwi apple banana

Ordenando objetos por vários campos

Encadeie comparadores para ordenar por um campo principal e, em seguida, por um campo secundário como critério de desempate:

record Employee(String name, String dept, int salary) {}

TreeSet<Employee> sorted = new TreeSet<>(
    Comparator.comparing(Employee::dept)
              .thenComparingInt(Employee::salary).reversed()
              .thenComparing(Employee::name)
);
sorted.add(new Employee("Alice", "Eng", 90_000));
sorted.add(new Employee("Bob",   "Eng", 85_000));
sorted.add(new Employee("Carol", "HR",  70_000));

for (Employee e : sorted) System.out.println(e.dept()+" "+e.name());

Consistência com equals

Regra crítica: o comparador usado por TreeSet/TreeMap define a igualdade para a coleção. Se comparator.compare(a, b) == 0, a e b são considerados a mesma chave — mesmo que a.equals(b) seja falso.

// Comparator ignoring case — "apple" and "APPLE" become the same key!
TreeSet<String> ci = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
ci.add("apple");
ci.add("APPLE"); // not added — same by comparator
System.out.println(ci.size()); // 1

TreeMap que ignora maiúsculas e minúsculas

Uma necessidade prática comum: uma TreeMap cujas chaves são strings que não diferenciam maiúsculas de minúsculas (útil para cabeçalhos HTTP e chaves de configuração):

TreeMap<String, String> headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
headers.put("Content-Type", "application/json");
headers.put("content-type", "text/html"); // overwrites!

System.out.println(headers.get("CONTENT-TYPE")); // text/html
System.out.println(headers.size()); // 1

Comparador seguro para valores nulos

Coleções baseadas em árvores com ordenação natural lançam NPE para chaves null. Use um comparador seguro para valores nulos que permita null como a menor chave:

TreeMap<String, Integer> map = new TreeMap<>(
    Comparator.nullsFirst(Comparator.naturalOrder())
);
map.put(null, 0);
map.put("b", 2);
map.put("a", 1);

map.forEach((k,v) -> System.out.println(k + "=" + v));
// null=0, a=1, b=2

Exemplo de objeto de domínio: Product por preço

Ordene produtos por preço em uma TreeSet, usando o nome como critério de desempate para manter a exclusividade:

record Product(String name, double price) {}

TreeSet<Product> catalog = new TreeSet<>(
    Comparator.comparingDouble(Product::price)
              .thenComparing(Product::name)
);
catalog.add(new Product("Widget", 9.99));
catalog.add(new Product("Gadget", 24.99));
catalog.add(new Product("Donut",  9.99));

catalog.forEach(p -> System.out.println(p.name() + " $" + p.price()));
// Donut $9.99, Widget $9.99, Gadget $24.99

Recuperando o comparador

Chame comparator() em uma TreeMap/TreeSet para recuperar o comparador personalizado. Retorna null quando a ordenação natural é usada.

TreeMap<String, Integer> map = new TreeMap<>(Comparator.reverseOrder());
System.out.println(map.comparator() != null); // true

TreeMap<String, Integer> natural = new TreeMap<>();
System.out.println(natural.comparator());      // null

Composição de comparadores

O Comparator do Java oferece métodos de fábrica encadeáveis para uma composição clara:

Comparator<String> comp =
    Comparator.comparingInt(String::length)   // by length
              .thenComparing(Comparator.naturalOrder()); // then alphabetically

TreeSet<String> ts = new TreeSet<>(comp);
ts.addAll(List.of("go", "java", "c", "rust", "py"));
ts.forEach(s -> System.out.print(s + " "));
// c go py java rust

Quando NÃO usar um comparador personalizado

Evite usar, em chaves de TreeMap ou elementos de TreeSet, um comparador que seja inconsistente com equals — isso causa entradas "ausentes" e confusas. Para obter o comportamento correto em todos os contextos de coleções, garanta que compare(a, b) == 0 se, e somente se, a.equals(b).

Verificação rápida

Uma TreeSet usa um comparador baseado apenas em String::length. O que acontece quando você adiciona "cat" e "dog"?

Recapitulação: ordenação personalizada

Principais pontos:

  • Passe um Comparator ao construtor de TreeMap/TreeSet para definir uma ordenação personalizada
  • A igualdade definida pelo Comparator determina a exclusividade nas coleções de árvore
  • Garanta que o comparador seja consistente com equals para evitar comportamentos inesperados
  • Use Comparator.nullsFirst/nullsLast para uma ordenação segura com valores nulos
  • Encadeie com thenComparing para ordenar por vários campos

Perguntas Frequentes

A aula “Ordenação Personalizada em Coleções Tree” é grátis?

Sim — o texto completo de “Ordenação Personalizada em Coleções Tree” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Java Academy, atualize para CoddyKit PRO. O curso de Java Academy inclui 4 aulas no total.

O que vou aprender em “Ordenação Personalizada em Coleções Tree”?

Forneça um Comparator a TreeMap ou TreeSet para definir ordens de classificação específicas do domínio. Você pratica Java Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Java Academy?

Nenhuma experiência prévia é necessária. Java Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.

Quanto tempo leva a aula “Ordenação Personalizada em Coleções Tree”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Java Academy?

Sim. Cada aula de Java Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. TreeMap: Pares Ordenados de Chave e Valor
  2. Submapas e Visões de Intervalos
  3. TreeSet e NavigableSet
  4. Ordenação Personalizada em Coleções Tree
← Voltar para Java Academy