ResumosMIEI

Uma coleção de resumos, para ajudar os que precisam daquele empurrão.


Project maintained by mendess Hosted on GitHub Pages — Theme by mattgraham

Comparable e Comparators

Um comparator serve para definir um critério pelo qual se podem comparar duas classes. Este tipo de comparações são normalmente usadas ordenar elementos de uma lista ou inserir corretamente numa árvore de procura.

Durante este resumo vai ser varias vezes referenciada a seguinte classe:

public class Aluno{
    private String nome;
    private int nota;
    /* construtores e getter/setters */
}

Comparators I

Para criar um comparator temos apenas de definir uma classe que implemente Comparator.

Se quisermos ordenar por ordem de notas, criamos o seguinte comparator.

public class AlunoComparator implements Comparator<Aluno>{
    public int compare(Aluno a1, Aluno a2){
        return Integer.compare(a1.getNota(), a2.getNota());
    }
}

Os tipos básicos (int, float, double, …) já tem definidos na respetiva classe métodos para os comparar.

Utilização

Método

Para o utilizar apenas temos de o passar a algum método ou construtor que necessite de um.

List<Aluno> alunosPorNota = new ArrayList<>();
// inserir montes de alunos
alunosPorNota.sort(new AlunoComparator());

Neste caso o método sort ira ordenar por ordem crescente de notas os alunos da lista.

Se quisermos ordenar pela ordem inversa podemos utilizar o método reversed disponibilizado por defeito em todos os Comparators

alunosPorNota.sort(new AlunosComparator().reversed());
Construtor

Para criar um SortedSet, neste caso, temos de passar um comparator ao criar uma instância.

SortedSet<Aluno> alunos = new TreeSet<>(new AlunoComparator());

Assim sempre que for adicionado um novo aluno a este TreeSet este irá ser inserido de forma ordenada.

Comparators II

Em vez de criarmos uma classe nova para comparar objetos de uma outra classe podemos também criar comparators com lambdas e outros métodos pré-definidos.

Utilização

Metodo

Utilizando a classe da secção anterior, os alunos podem ser ordenados das seguintes formas.

O primeiro pode também ser invertido. [1]

alunosPorNota.sort(Comparator.comparingInt(Aluno::getNota).reversed());

Comparable ou “ordem natural”

Outro método de comparar objetos de uma classe é fazer essa classe comparável.

Metodo

Podemos definir que, por defeito, os Alunos podem ser comparados por nome implementando a interface Comparable, que obriga à implementação do método compareTo.

public class Aluno implements Comparable<Aluno> {
    private String nome;

    public int compareTo(Aluno aluno){
        return this.nome.compareTo(aluno.getNome());
    }
} 

Nota: As strings são Comparable.

Podemos agora ter uma lista ordenada por nome da seguinte forma:

alunosPorNome.sort(Comparator.naturalOrder());
Construtor

Agora que Aluno é Comparable podemos criar uma estrutura ordenada sem nos preocuparmos com o comparator::

SortedSet<Aluno> alunos = new TreeSet<>();

Extra Notes

  1. Para inverter o lambda temos de expandi-lo para o que ele verdadeiramente é:
     alunosPorNome.sort((new Comparator<Aluno>() {
         @Override
         public int compare(Aluno a1, Aluno a2){
             return a1.getNome().compareTo(a2.getNome());
         }
     }).reversed());
    

    A isto chama-se uma classe anónima, que faz uso da interface funcional Comparator.