🧠 Objetivo do Tópico
Aprender:
- Como ordenar objetos personalizados com
ComparableeComparator - Diferenças entre ambos
- Boas práticas, formas corretas e incorretas
- Sintaxe com classes anônimas, expressões lambda e métodos estáticos de comparação
- Dicas de prova + 10 questões com respostas comentadas
🔍 1. Interface Comparable<T>
Você implementa essa interface na própria classe para definir ordem natural.
Exemplo: ordenando por nome (ordem alfabética)
public class Pessoa implements Comparable<Pessoa> {
private String nome;
private int idade;
public Pessoa(String nome, int idade) {
this.nome = nome;
this.idade = idade;
}
@Override
public int compareTo(Pessoa outra) {
return this.nome.compareTo(outra.nome);
}
@Override
public String toString() {
return nome + " (" + idade + ")";
}
}
List<Pessoa> lista = new ArrayList<>();
lista.add(new Pessoa("João", 30));
lista.add(new Pessoa("Ana", 25));
lista.add(new Pessoa("Carlos", 20));
Collections.sort(lista);
System.out.println(lista);
Saída: [Ana (25), Carlos (20), João (30)]
→ Ordem natural foi definida pelo compareTo().
🔀 2. Interface Comparator<T>
Você cria um comparador externo, útil quando:
- Quer várias formas de ordenação
- Não pode/quer modificar a classe original
Exemplo: ordenando por idade
Comparator<Pessoa> porIdade = new Comparator<>() {
@Override
public int compare(Pessoa p1, Pessoa p2) {
return Integer.compare(p1.idade, p2.idade);
}
};
Collections.sort(lista, porIdade);
Ou usando lambda:
lista.sort((p1, p2) -> Integer.compare(p1.idade, p2.idade));
Ou com método de comparação:
lista.sort(Comparator.comparing(p -> p.idade));
❌ Erros comuns (pegadinhas)
- Usar
compareToretornando boolean — precisa retornarint - Esquecer de sobrescrever
compareTo()se usaComparable - Confundir
ComparatorcomComparableem provas - Esquecer que
Comparatorpermite múltiplos critérios (ex:.thenComparing()) - Usar
==para comparar Strings ao invés decompareToouequals
✅ Boas práticas
- Use
Comparablepara ordem natural (ex: nomes, números) - Use
Comparatorpara outras ordenações (ex: por data, idade, tamanho) - Use
Comparator.comparing()com lambdas para código limpo - Use
thenComparing()para empates
📘 Exemplo com thenComparing
Comparator porIdadeENome = Comparator
.comparing(Pessoa::getIdade)
.thenComparing(Pessoa::getNome);
⌛Simulado
1. Qual método Comparable exige implementação?
Resposta: D
a) equals
b) hashCode
c) compare
d) compareTo
2. O que Collections.sort(lista) exige?
Resposta: C
a) Que o objeto use Comparator
b) Que a lista seja de Strings
c) Que os elementos implementem Comparable
d) Que a lista esteja ordenada
3. Qual o propósito de Comparator<T>?
Resposta: B
a) Substituir equals
b) Definir ordem de objetos sem modificar a classe original
c) Comparar objetos usando hashCode
d) Ser usado apenas com mapas
4. Dado:
Resposta: B
class Produto {
String nome;
double preco;
}
Qual opção ordena por preço usando lambda?
a) lista.sort((a, b) -> a.preco - b.preco);
b) lista.sort((a, b) -> Double.compare(a.preco, b.preco));
c) lista.sort((a, b) -> a.preco > b.preco);
d) Collections.sort(lista, Produto);
5. O que compareTo() deve retornar?
Resposta: B
a) true se objetos forem iguais
b) um número negativo, zero ou positivo
c) o menor número
d) uma String
6. É possível usar Comparator com TreeSet?
Resposta: B
a) Não
b) Sim, passando no construtor
c) Sim, desde que a classe seja abstract
d) Apenas se a classe implementar Comparable
7. Qual método combina dois comparadores?
Resposta: C
a) combine()
b) compareWith()
c) thenComparing()
d) alsoCompare()
8. Qual dessas expressões é inválida?
Resposta: B
a) Comparator.comparingInt(p -> p.idade);
b) Comparator.compare((a, b) -> a.idade);
c) Comparator.comparing(p -> p.nome);
d) Comparator.comparing(Pessoa::getIdade);
9. Quando dois objetos têm compareTo() == 0, eles são:
Resposta: B
a) Idênticos fisicamente
b) Considerados iguais na ordenação
c) Diferentes
d) Necessariamente null
10. O que acontece se dois objetos forem “iguais” em um TreeSet?
Resposta: B
a) Ambos são armazenados
b) Apenas um é armazenado
c) Gera exceção
d) Ordenação é ignorada
✅ Gabarito com Comentários
- d –
compareToé o método da interfaceComparable. - c –
Comparabledefine a ordem natural. - b –
Comparatorpode ordenar sem modificar a classe. - b –
Double.compareé a maneira correta. - b –
compareTo()retorna int, e deve indicar a ordem. - b –
TreeSetaceita umComparatorno construtor. - c –
thenComparingencadeia comparações. - b –
Comparator.compare()não existe, écompare(a, b)via instância. - b –
compareTo() == 0indica “iguais na ordenação”, nãoequals(). - b –
TreeSetdescarta duplicatas baseadas na ordenação.
🧾 Resumo
Comparable: implementado na própria classe, define a ordem natural.Comparator: externo, pode ter múltiplas ordens e ser combinado.- Métodos importantes:
compareTo(T o)→Comparablecompare(T o1, T o2)→ComparatorComparator.comparing,thenComparing,reversed()
- Saber usar ambos é essencial para ordenações com
Collections.sort,TreeSet,TreeMap, etc.