Como substituir corretamente o método equals em Java?
sobes.tech IA
Resposta da IA
// Exemplo de redefinição mínima correta de equals
class MyClass {
private int id;
private String name;
public MyClass(int id, String name) {
this.id = id;
this.name = name;
}
@Override // Anotação obrigatória
public boolean equals(Object o) {
// 1. Verificação de identidade
if (this == o) return true;
// 2. Verificação de null e correspondência de classes
// Usamos getClass() para uma verificação estrita
if (o == null || getClass() != o.getClass()) return false;
// 3. Casting
MyClass myClass = (MyClass) o;
// 4. Comparação de campos significativos
return id == myClass.id &&
// Usamos Objects.equals para comparar objetos (considera null)
Objects.equals(name, myClass.name);
}
}
Regras para uma redefinição correta de equals (de acordo com o contrato de Object.equals):
- Reflexividade: Para qualquer valor não nulo
x,x.equals(x)deve retornartrue. - Simetria: Para quaisquer valores não nulos
xey,x.equals(y)deve retornartruese e somente sey.equals(x)retornartrue. - Transitividade: Para
x,y, eznão nulos, sex.equals(y)ey.equals(z)sãotrue, entãox.equals(z)deve sertrue. - Consistência: Para
xeynão nulos, múltiplas chamadas ax.equals(y)devem retornar de forma consistentetrueoufalse, desde que a informação usada para a comparação não mude. - Para qualquer valor não nulo
x,x.equals(null)deve retornarfalse.
Recomenda-se usar Objects.equals(obj1, obj2) para comparar objetos de forma segura, pois ele lida corretamente com null.
Sempre sobrescreva hashCode() ao sobrescrever equals(), em conformidade com o contrato geral de Object.hashCode: se dois objetos são iguais de acordo com equals(Object), seus códigos hash, retornados por hashCode(), devem ser iguais. A condição inversa não é obrigatória. Não cumprir essa regra pode causar um funcionamento incorreto de coleções baseadas em tabelas hash (por exemplo, HashMap, HashSet).
// Exemplo de hashCode correspondente para MyClass
class MyClass {
private int id;
private String name;
// ... construtor e equals como acima ...
@Override
public int hashCode() {
// Uso de Objects.hash para calcular o hash de forma conveniente
return Objects.hash(id, name);
}
}
Pode gerar automaticamente os métodos equals e hashCode usando IDEs (IntelliJ IDEA, Eclipse), o que é uma boa prática.
Use instanceof em vez de getClass() apenas se a classe fizer parte de uma hierarquia de herança e você precisar que objetos de superclasse e subclasse sejam considerados iguais se tiverem o mesmo estado. Na maioria dos casos, é preferível usar getClass() para uma verificação estrita.