Um breve papo sobre Coleções (Pt. 2) - O famoso Comparator
- #Java
Um conceito muito presente na manipulação de objetos em Coleções é o da comparação de objetos. Para tal finalidade, o Java possui a interface Compartor.
O que é o Comparator?
É uma interface que permite comparar objetos e ordená-los.
Qual é o critério de ordenação usado pela interface?
QUALQUER UM! Você como dev escolhe como será o processo de ordenação
Existe uma relação quase que umbilical entre as Collections e os Comparators, pois os Comparators são usados como condição de ordenamento.
Vamos exemplificar?
Imagine a seguinte classe
public class Pessoa {
private String nome;
private Integer idade;
public Pessoa(String nome, int idade){
this.nome = nome;
this.idade = idade;
}
public String getNome(){return this.nome;}
public Integer getIdade(){return this.idade;}
@Override
public String toString(){
return "Pessoa("+this.nome+", "+this.idade+")";
}
}
Como fariamos para ordenar uma lista de pessoas por idade (do mais jovem para o mais velho) como primerio critério e como critério secundário usar o nome como parâmetro de comparação?
Para isso, usamos o método compareTo nas seguintes classes padrão do Java:
- java.lang.Byte
- java.lang.Short
- java.lang.Integer
- java.lang.Long
- java.lang.Float
- java.lang.Double
- java.lang.Character
- java.lang.String
- java.math.BigDecimal
- java.math.BigInteger
- java.time.LocalDate
- java.time.LocalDateTime
- java.time.LocalTime
- java.time.MonthDay
- java.time.OffsetDateTime
- java.time.OffsetTime
- java.time.Year
- java.time.YearMonth
- java.time.ZonedDateTime
Vamos entender o funcionamento do método compareTo. Ele sempre retorna um inteiro!
objeto1.copareTo(objeto2)
O retorno é dado da seguinte forma:
Se E > D : compareTo int > 0
Se D < E : compareTo int < 0
Se D = E : compareTo int = 0
Onde E é esquerda e D direita
O método .sort() da interface List, consegue ordenar objetos através da passagem da implementação de um Compartor em seu argumento. Desta forma:
public class Main {
public static void main(String[] args) {
List<Pessoa> pessoas = new ArrayList<>();
pessoas.add(new Pessoa("Lucas",32));
pessoas.add(new Pessoa("Bruno",12));
pessoas.add(new Pessoa("Caio",32 ));
pessoas.add(new Pessoa("Leonardo",22));
pessoas.add(new Pessoa("Amanda",32));
pessoas.add(new Pessoa("Laura",22));
System.out.println("Lista Antes (Sem Comparable): "+ pessoas.toString());
pessoas.sort(new Comparator<Pessoa>() {
@Override
public int compare(Pessoa pessoa1, Pessoa pessoa2) {
if(pessoa1.getIdade().compareTo(pessoa2.getIdade())!=0) return pessoa1.getIdade().compareTo(pessoa2.getIdade());
return pessoa1.getNome().compareTo(pessoa2.getNome());
}
});
System.out.println("Lista Depois (Sem Comparable): "+ pessoas.toString());
}
}
Observe que a interface Compartor<Pessoa> é implementada dentro do argumento do método sort()
Comparator<Pessoa>() {
@Override
public int compare(Pessoa pessoa1, Pessoa pessoa2) {
if(pessoa1.getIdade().compareTo(pessoa2.getIdade())!=0) return pessoa1.getIdade().compareTo(pessoa2.getIdade());
return pessoa1.getNome().compareTo(pessoa2.getNome());
}
}
Podemos fazer isso de outra forma, fazendo que nosso objeto se torne um objeto comparável, eliminando assim a necessidade da implementação de um compartor para ordenar itens de uma lista:
public class PessoaComparable implements Comparable<PessoaComparable>{
private String nome;
private Integer idade;
public PessoaComparable(String nome, int idade){
this.nome = nome;
this.idade = idade;
}
public String getNome(){return this.nome;}
public Integer getIdade(){return this.idade;}
@Override
public int compareTo(PessoaComparable pessoaComparable) {
if(pessoaComparable.getIdade().compareTo(this.getIdade())!=0)
return pessoaComparable.getIdade().compareTo(this.getIdade());
return pessoaComparable.getNome().compareTo(this.getNome());
}
@Override
public String toString(){
return "Pessoa("+this.nome+", "+this.idade+")";
}
}
Deste modo, podemos realizar a ordenação da lista através de uma chamada lambda, no argumento do método sort() conforme mostrado logo abaixo:
public class Main {
public static void main(String[] args) {
List<PessoaComparable> pessoasComparables = new ArrayList<>();
pessoasComparables.add(new PessoaComparable("Lucas",32));
pessoasComparables.add(new PessoaComparable("Bruno",12));
pessoasComparables.add(new PessoaComparable("Caio",32 ));
pessoasComparables.add(new PessoaComparable("Leonardo",22));
pessoasComparables.add(new PessoaComparable("Amanda",32));
pessoasComparables.add(new PessoaComparable("Laura",22));
System.out.println("Lista Antes: "+ pessoasComparables.toString());
pessoasComparables.sort((p1, p2) -> p2.compareTo(p1));
System.out.println("Lista Depois: "+ pessoasComparables.toString());
}
}
Irei deixar uma pequena atividade para aqueles que se interessarem:
Parafraseando o falecido Marcelo Rezende: "Aí eu te pergunto..." Como faço para criar uma ordenação do mais velho para o mais jovem de Z-A ? Resolva das duas formas.
That's all folks!