Hashcode e equals

Amigolhes, eu não sei se vocês sabem, mas caso vocês sobrescrevam o método equals no java, vc é obrigado a implementar o método hashCode.

Isso porque o equals e o hashcode, originados da classe Object tem um contrato e essa quebra de contrato pode causar mal funcionamento em alguns algoritmos, como por exemplo em collections (ex. HashMap)

O método hashCode devolve, na implementação do Object, o endereço de memória do objeto. O objetivo do método é devolver um identificador para o objeto (de preferência único).

Já o método equals testa se 2 objetos são iguais. A implementação base da classe Object compara, para isso, o identificador único da classe definido pelo método hashCode (ou seja, compara os endereços de memória dos objetos).

Vem dai o contrato do equals e do HashCode estabelecidos na classe Object. As estruturas de dados do Collection (ArrayList, HashMap, etc) se baseiam nesses dois métodos para comparar objetos, testá-los e posicioná-los dentro de sua estrutura

Logo, se você fizer algo assim…

public class Money {
public int amount;
public boolean equals (Object obj) {
Money m = (Money) obj;
if (m.amount==amount)
return true;
else
return false;
}
}

… para manter o contrato entre o hashCode e o equals, você deveria sobrescrever o método hashCode com algo que identifique a classe de modo a distingui-la das demais da mesma forma que foi feito no método sobrescrito equals, ou seja, desse modo:


public int hashCode (Object obj) {
return money;
}

outro método útil seria calcular o MD5 da string com todos os valores conferidos no método equals concatenado (caso a classe possuísse mais valores e o equals testasse esses valores também). Fica a critério do freguês bolar a melhor forma de identificar unicamente seu objeto utilizando o mesmo critério usado no método equals.

Agora, se você ficou triste por ter sobrescrito o hashCode e perdido a informação do endereço de memória do objeto, você pode obte-lo dessa maneira:

int enderecoMemoria = System.identityHashCode ( seuObjeto);

Bom, só fui ver isso hoje porque o checkstyle reclamou de eu ter violado o tal do contrato. A fonte pra tudo isso ai em cima, em ingrês, foi: http://www.javaworld.com/community/node/1006

Anúncios

Deixe um comentário

Arquivado em Desenvolvimento, Java

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s