Qual numero é maior, 1 ou 928? Que palavra vem primeiro no dicionário “abacate” ou “banana”?
Pra essas perguntas as respostas são fáceis, mas dado dois objetos do tipo Carro, qual deve ser colocado primeiro que o outro em uma ordenação?
Pra essas situações, em que um objeto deve ser comparável, Java define abordagens diferentes, são elas o uso da interface Comparable no objeto que se deseja comparar, ou o implementação da interface Comparator para os objetos que se deseja declarar.
Ambas as interfaces são extremamente simples. A interface comparable define o método int compareTo(T o). Quando um objeto que implementa Comparable vai ser comparado com outro, o método compareTo daquele objeto é invocado passando como argumento o objeto com que se quer comparar. Se o retorno da chamada for um número maior que zero, é considerado que o objeto em que está se chamando o método é maior que o objeto que está sendo passado como parâmetro, se o retorno for menor que zero, quer dizer que o objeto passado como parâmetro é maior que o objeto em que esta sendo feita a chamada, se os dois objetos forem considerados iguais, então o retorno deve ser zero.
Já a interface Comparator define o método int compare(T1 o1, T2 o2). Um objeto que implementa comparator, deve fazê-lo de tal forma que se o1 for maior que o2, o retorno deve ser um valor positivo, se o1 for menor que 02, o retorno deve ser um valor negativo, e se os objetos forem iguais, os dois objetos são iguais.
Vamos a um exemplo para demonstrar os usos dos dois:
Considere a classe carro a seguir:
public class Carro {
public String marca;
public String modelo;
public String cor;
public Integer ano;
public Integer valorTabela;
public Integer quilometragem;
public Short velocidadeMaxima;
@Override
public String toString() {
return marca + ” “ + modelo + ” “ + cor + ” “ + ano;
}
}
Queremos agora fazer com que a ordem natural desses carros seja dada pelas marcas em ordem alfabética, e em caso de carros da mesma marca a ordenação deve ser dada pelo modelo, também em ordem alfabética, e em caso de carros do mesmo modelo, a ordem é dada pelo Ano, do mais antigo para o mais novo.
Como estamos falando da ordem natural dos Objetos, devemos implementar a interface Comparable, e com isso o método compareTo na nossa classe Carro:
public int compareTo(Carro carro) {
if (this.marca.compareTo(carro.marca) != 0) {
return this.marca.compareTo(carro.marca);
}
if (this.modelo.compareTo(carro.modelo) != 0) {
return this.modelo.compareTo(carro.modelo);
}
return this.ano.compareTo(carro.ano);
}
A segunda coisa que queremos é ter uma lista com os carros ordenados por seu valor de venda, esse valor é dado primeiro pelo valor de tabela, caso esse seja o mesmo, é dado pelo ano, do mais novo para o mais velho, e caso sejam do mesmo ano, pela quilometragem, do menos rodado para o mais rodado. Como o nosso objeto carro já implementa o método compareTo para definir sua ordem natural, não podemos usá-lo para definir a ordem por valor venal, mas podemos implementar um Comparator que faça essa comparação:
private class ValorVenalComparator
implements Comparator
{
public int compare(Carro o1, Carro o2) {
if (o1.valorTabela.compareTo(o2.valorTabela) != 0) {
return -1 * o1.valorTabela.compareTo(o2.valorTabela);
}
if (o1.ano.compareTo(o2.ano) != 0) {
return -1 * o1.ano.compareTo(o2.ano);
}
return o1.quilometragem.compareTo(o2.quilometragem);
}
}
O código final para a exibição da lista de carros ordenada das duas formas é o seguinte:
public class OrdenadorDeCarros {
List lista = new ArrayList();
public void listarOrdemNatural() {
Collections.sort(lista);
for (Carro carro : lista) {
System.out.println(carro);
}
}
public void ordenarValorVenal() {
Collections.sort(lista, new ValorVenalComparator());
for (Carro carro : lista) {
System.out.println(carro);
}
}
public static void main (String[] args) {
OrdenadorDeCarros ordenador = new OrdenadorDeCarros();
Carro fusca = new Carro();
fusca.marca = “Volks”;
fusca.modelo = “Fusca”;
fusca.cor = “Laranja”;
fusca.ano = 1976;
fusca.quilometragem = 1800000;
fusca.valorTabela = 4300;
fusca.velocidadeMaxima = 100;
ordenador.lista.add(fusca);
Carro fusca2 = new Carro();
fusca2.marca = “Volks”;
fusca2.modelo = “Fusca”;
fusca2.cor = “Azul”;
fusca2.ano = 1989;
fusca2.quilometragem = 128000;
fusca2.valorTabela = 5600;
fusca2.velocidadeMaxima = 103;
ordenador.lista.add(fusca2);
Carro _147 = new Carro();
_147.marca = “Fiat”;
_147.modelo = “147″;
_147.cor = “Cinza”;
_147.ano = 1989;
_147.quilometragem = 109000;
_147.valorTabela = 4200;
_147.velocidadeMaxima = 70;
ordenador.lista.add(_147);
Carro monza = new Carro();
monza.marca = “GM”;
monza.modelo = “Monza”;
monza.cor = “Branco”;
monza.ano = 1989;
monza.quilometragem = 95000;
monza.valorTabela = 5600;
monza.velocidadeMaxima = 140;
ordenador.lista.add(monza);
ordenador.listarOrdemNatural();
System.out.println();
System.out.println(” — Ordena Por Valor”);
System.out.println();
ordenador.ordenarValorVenal();
}
}