quarta-feira, 12 de abril de 2017

Ordenando um ArrayList em Java

Ordenando uma lista de objetos em Java


Como exemplo usaremos as informações da classe Aluno:
public class Aluno {
 
     private final String nome;
     private int pontos;
 
     public Aluno(String nome, int pontos) {
          this.nome = nome;
          this.pontos = pontos;
     }
 
     //métodos
 
}
Então vamos criar nossos alunos:
Aluno aluno1 = new Aluno("Alex Felipe"13450);
Aluno aluno2 = new Aluno("Maurício Aniche"19930);
Aluno aluno3 = new Aluno("Guilherme Silveira"23143);
Aluno aluno4 = new Aluno("Rodrigo Turini"13500);
Agora precisamos de uma List para armazenar esses alunos:
List<Aluno> alunos = new ArrayList<Aluno>();
 
alunos.add(aluno1);
alunos.add(aluno2);
alunos.add(aluno3);
alunos.add(aluno4);
Testando a nossa lista:
System.out.println(alunos);
Resultado:
[Alex Felipe - 13450, Maurício Aniche - 19930,
Guilherme Silveira - 23143, Rodrigo Turini - 13500]
Pronto! Tenho minha List com os alunos. Agora vamos ordenar com o método estático sort() da classe Collections():
Collections.sort(alunos);
Espere um pouco… O meu código não compila!? O problema é que o método sort() não sabe como ordenar um aluno, ou seja, ele não sabe qual parâmetro ou critério deve usar para comparar alunos. Porém, nós podemos informá-lo implementando a interface Comparable na classe Aluno:
public class Aluno implements Comparable<Aluno>{
 
     //atributos e métodos
 
     @Override
     public int compareTo(Aluno outroAluno) {
         //implementação
     }
 
}
Quando implementamos a interface Comparable, precisamos preencher o campo do generics com o tipo de objeto que queremos comparar, nesse caso queremos comparar com Aluno mesmo. Por fim, precisamos implementar o método compareTo().
A regra de ordenação usando o método compareTo() compara dois objetos (alunos) e funciona da seguinte maneira:
  • Para alocar o aluno mais a esquerda da lista, retornamos -1.
  • Para alocar o aluno mais a direita da lista, retornamos 1.
  • quando retornamos 0 significa que os alunos comparados são iguais e não alteram suas posições.
No nosso exemplo:
@Override
public int compareTo(Aluno outroAluno) {
     if (this.pontos > outroAluno.getPontos()) {
          return -1;
     }
     if (this.pontos < outroAluno.getPontos()) {
          return 1;
     }
     return 0;
}
Estamos indicando que se os pontos do aluno forem maior, mande ele mais para esquerda (-1), se for menor, mande para a direita (1) e se os alunos forem iguais não faça nada (0).
Após a implementação do Comparable, o nosso código compila! Vamos testá-lo:
Collections.sort(alunos);
System.out.println(alunos);
Resultado:
[Guilherme Silveira - 23143, Maurício Aniche - 19930,
Rodrigo Turini - 13500, Alex Felipe - 13450]
Veja que agora os nossos alunos estão ordenados!
Diferente da ordenação de números, para ordenar lista de objetos específicos, como é o caso do objeto aluno, é necessário informar como o objeto precisa ser ordenado implementando a interface Comparable e implementando o seu método compareTo(). Há um post da Caelum que explica com mais detalhes essa e outras formas de ordenação de coleções.