Como comparar objetos em Java?

Eu tenho uma lista de livros os quais já comprei:

public class Livro {

     private String nome;
     private String autor;
     private double preco;

     public Livro(String nome, String autor, double preco) {
          this.nome = nome;
          this.autor = autor;
          this.preco = preco;
     }

     //métodos

}

List<Livro> meusLivros = todosOsLivros();

System.out.println(meusLivros);

Resultado:

[TDD - Maurício Aniche, Java 8 - Paulo Silveira, C# - Everton Coimbra, 
REST - Alexandre Saudate, Android - João Bosco]

Agora testarei minha lista e verificarei se ela sabe conferir se um livro que já comprei está na lista:

Livro novo = new Livro("TDD", "Maurício Aniche", 25.00);

if (jaExiste(novo)) {
     System.out.println("contém");
     } else {
     System.out.println("não contém");
     }
}

private static boolean jaExiste(Livro novo) {
     if (todosOsLivros().contains(novo)) {
          return true;
     }
          return false;
     }
}

Resultado:

não contém

Opa! Eu já comprei esse livro de TDD! Essa lista está doida? Ela não conseguiu verificar a existência desse livro, pois cada objeto possui um código chamado hashcode e é por meio desse código que qualquer objeto é identificado, por padrão. Vamos, por exemplo, imprimir dois objetos aparentemente “iguais” sem um toString() personalizado, ou seja, o padrão:

Livro livro1 = new Livro("TDD", "Maurício Aniche", 25.00);
Livro livro2 = new Livro("TDD", "Maurício Aniche", 25.00);

System.out.println(livro1);
System.out.println(livro2);

Resultado:

model.Livro@2a139a55
model.Livro@15db9742

Veja que, mesmo tendo as mesmas informações, as impressões foram diferentes! Por isso a lista informou que o livro de TDD não existia. Para personalizar a comparação de um objeto precisamos sobrescrever o método equals() herdado da classe Object:

public class Livro {

     //métodos e atributos

     @Override
     public boolean equals(Object obj) {
          //implementação
     }

}

Agora iremos implementar o método equals() informando que os livros são iguais desde que os nomes sejam iguais:

@Override
public boolean equals(Object livro) {
     if (this.nome == ((Livro) livro).getNome()){
          return true;
     }
     return false;
}

Testando a nossa lista novamente:

Livro novo = new Livro("TDD", "Maurício Aniche", 25.00);
		
if (jaExiste(novo)) {
     System.out.println("contém");
     } else {
     System.out.println("não contém");
}

Resultado:

contém

Maravilha! A nossa lista está conseguindo verificar se um determinado livro existe! Mas e se o autor for diferente? Ela vai informar que existe… Da mesma forma que informamos que queríamos a comparação do livro por meio do nome, podemos informar que queremos que o livro seja comparado pelo nome e autor, ao mesmo tempo:

@Override
public boolean equals(Object livro) {
     if (this.nome == ((Livro) livro).getNome() 
          && this.autor == ((Livro) livro).getAutor()){
          return true;
     }
     return false;
}

Vamos testar nossa lista novamente:

Livro novo = new Livro("TDD", "João da Silva", 25.00);

if (jaExiste(novo)) {
     System.out.println("contém");
     } else {
     System.out.println("não contém");
     }
}

Resultado

não contém

Agora todos os objetos do tipo Livro são corretamente comparados e, assim, eu posso sempre pedir para a minha lista de livros verificar se eu já tenho um determinado livro antes de comprá-lo! Todas as vezes que precisarmos fazer comparação entre objetos, será necessário sobrescrever o método equals() herdado da classe Object e implementar qual é o tipo de comparação que você precisa, seja por 1 atributo específico, ou por 2, ou por todos.

E aí, gostou da forma que comparamos objetos em Java? Que tal aprofundar mais nos detalhes dessa linguagem? Pensando nisso o instrutor Guilherme Silveira, criou a trilha de certificação Java no Alura, com 9 cursos especializados para se preparar para a certificação da Oracle!


Content Editor at Alura and Software Developer

  • Edson Roberto Rezende

    Excelente.

    • Edson, fico contente que tenha gostado!
      Muito obrigado pelo comentário 🙂

  • Leandro

    Muito bom, obrigado.

    • Leandro, obrigado pelo seu comentário, fico contente em saber que gostou 🙂

Próximo ArtigoDesafio Alura - criando um projeto com Spring Boot em 5 minutos