Os programadores frequentemente precisam classificar elementos de um banco de dados em uma coleção, array ou mapa. Em Java, podemos implementar qualquer algoritmo de classificação que quisermos com qualquer tipo.
Usando o Comparable
interface e compareTo()
método, podemos classificar usando ordem alfabética, String
comprimento, ordem alfabética reversa ou números. O Comparator
interface nos permite fazer o mesmo, mas de uma forma mais flexível.
O que quer que queiramos fazer, só precisamos saber como implementar a lógica de classificação correta para determinada interface e tipo.
Classificando com interfaces Comparable e Comparator do Java
Aqui está o que você aprenderá neste artigo sobre classificação de objetos Java:
- Classificando com
Comparable
:- Classificando um Java
List
- Como o Java
compareTo()
funciona - Como classificar arrays em Java
- Classificando um Java
Map
comTreeMap
- Classificando um Java
Set
comTreeSet
- Como evitar
ClassCastException
s ao classificar - Usando
Comparable
com as principais classes Java
- Classificando um Java
- Classificando com
Comparator
:- Usando
Comparator
com classes internas anônimas - Usando
Comparator
com expressões lambda
- Usando
Classificando com Comparável
Começaremos explicando como classificar usando a interface Comparable do Java. Nós usamos Comparable
quando há uma única comparação padrão para o objeto que queremos classificar.
Classificando uma lista Java
Neste primeiro exemplo, implementamos Comparable
em um Simpson
classe, usando Simpson
no tipo genérico:
class Simpson implements Comparable<Simpson> {
String name;
Simpson(String name) {
this.name = name;
}
@Override
public int compareTo(Simpson simpson) {
return this.name.compareTo(simpson.name);
}
}
public class SimpsonSorting {
public static void main(String... sortingWithList) {
List<SimpsonCharacter> simpsons = new ArrayList<>();
simpsons.add(new SimpsonCharacter("Homer "));
simpsons.add(new SimpsonCharacter("Marge "));
simpsons.add(new SimpsonCharacter("Bart "));
simpsons.add(new SimpsonCharacter("Lisa "));
Collections.sort(simpsons);
simpsons.stream().map(s -> s.name).forEach(System.out::print);
Collections.reverse(simpsons);
simpsons.stream().forEach(System.out::print);
}
}
Observe que substituímos o método compareTo() e passamos outro Simpson
objeto. Também substituímos o toString()
método, apenas para tornar o exemplo mais fácil de ler.
Como funciona o compareTo() do Java
O compareTo()
O método compara um determinado objeto ou a instância atual com um objeto especificado para determinar a ordem dos objetos. Aqui está uma rápida olhada em como compareTo()
funciona.
Só podemos usar classes que sejam comparáveis com o sort()
método. Se tentarmos passar um Simpson
que não implementa Comparable
receberemos um erro de compilação.
O sort()
método usa polimorfismo passando qualquer objeto que seja Comparable
. Os objetos serão então classificados conforme o esperado.
A saída do código anterior seria:
Bart Homer Lisa Marge
Se quiséssemos reverter a ordem, poderíamos trocar o sort()
para reverse()
; de:
Collections.sort(simpsons);
para:
Collections.reverse(simpsons);
Implantando o reverse()
método mudaria a saída anterior para:
Marge Lisa Homer Bart
Como classificar um array Java
Em Java, podemos classificar um array com qualquer tipo que quisermos, desde que implemente o Comparable
interface. Aqui está um exemplo:
public class ArraySorting {
public static void main(String... moeTavern) {
int() moesPints = new int() {9, 8, 7, 6, 1};
Arrays.sort(moesPints);
Arrays.stream(moesPints).forEach(System.out::print);
Simpson() simpsons = new Simpson(){new Simpson("Lisa"), new Simpson("Homer")};
Arrays.sort(simpsons);
Arrays.stream(simpsons).forEach(System.out::println);
}
}
Em primeiro sort()
invocação, a matriz é classificada para:
1 6 7 8 9
No segundo sort()
invocação, ele é classificado para:
Homer Lisa
Lembre-se de que os objetos personalizados devem implementar Comparable
para ser classificado, mesmo como uma matriz.
Como evitar ClassCastExceptions ao classificar objetos Java
Se o objeto Simpson não estivesse sendo implementado Comparable
, uma ClassCastException seria lançada. Se você executar isso como um teste, verá algo como o seguinte resultado:
Error:(16, 20) java: no suitable method found for sort(java.util.List<com.javaworld.javachallengers.sortingcomparable.Simpson>)
method java.util.Collections.<T>sort(java.util.List<T>) is not applicable
(inference variable T has incompatible bounds
equality constraints: com.javaworld.javachallengers.sortingcomparable.Simpson
lower bounds: java.lang.Comparable<? super T>)
method java.util.Collections.<T>sort(java.util.List<T>,java.util.Comparator<? super T>) is not applicable
(cannot infer type-variable(s) T
(actual and formal argument lists differ in length))
Este log pode ser confuso, mas não se preocupe. Basta ter em mente que um ClassCastException
será lançado para qualquer objeto classificado que não implemente o Comparable
interface.
Classificando um mapa com TreeMap
A API Java inclui muitas classes para auxiliar na classificação, incluindo TreeMap. No exemplo abaixo, usamos TreeMap
para classificar chaves em um Map
.
public class TreeMapExample {
public static void main(String... barney) {
Map<SimpsonCharacter, String> simpsonsCharacters = new TreeMap<>();
simpsonsCharacters.put(new SimpsonCharacter("Moe"), "shotgun");
simpsonsCharacters.put(new SimpsonCharacter("Lenny"), "Carl");
simpsonsCharacters.put(new SimpsonCharacter("Homer"), "television");
simpsonsCharacters.put(new SimpsonCharacter("Barney"), "beer");
System.out.println(simpsonsCharacters);
}
}
TreeMap
usa o compareTo()
método implementado pelo Comparable
interface. Cada elemento no resultado Map
é classificado por sua chave. Neste caso, a saída seria:
Barney=beer, Homer=television, Lenny=Carl, Moe=shotgun
Lembre-se, porém: se o objeto não implementar Comparable
você receberá um ClassCastException
.
Classificando um conjunto com TreeSet
O Set
interface é responsável por armazenar valores únicos, mas quando usamos a implementação TreeSet, os elementos inseridos serão ordenados automaticamente à medida que os adicionamos:
public class TreeSetExample {
public static void main(String... barney) {
Set<SimpsonCharacter> simpsonsCharacters = new TreeSet<>();
simpsonsCharacters.add(new SimpsonCharacter("Moe"));
simpsonsCharacters.add(new SimpsonCharacter("Lenny"));
simpsonsCharacters.add(new SimpsonCharacter("Homer"));
simpsonsCharacters.add(new SimpsonCharacter("Barney"));
System.out.println(simpsonsCharacters);
}
}
A saída deste código é:
Barney, Homer, Lenny, Moe
Novamente, se usarmos um objeto que não é Comparable
obteremos um ClassCastException
.