Article image
Caio Oliveira
Caio Oliveira03/05/2023 18:34
Compartilhe

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!

Compartilhe
Comentários (0)