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](http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html)
:
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 Formação Java na Alura.