Relação hashCode x equals

Srs., bom dia!

Não consigo entender a relação hashCode e equals. Um chama o outro?

Att,

Thiago Freitas

[quote=thiagolgf]Srs., bom dia!

Não consigo entender a relação hashCode e equals. Um chama o outro?

Att,

Thiago Freitas[/quote]
Não.

Você chegou a ler algo sobre o assunto? Se sim, o que?

Olá!

Estou usando como base de estudo a apostila da Caelum “FJ-11 Java e Orientação a Objetos” e na net li alguns artigos sobre tabela de espalhamento e como os objetos são guardados e percorridos a partir do seu hashCode, mas não entendi o que o hashCode conversa com o equals.

Att,

Thiago Freitas

dá uma lida se você manja em inglês.

acho que ajuda.

Eles não conversam.

Aparentemente você entendeu o funcionamento do hashCode, isso já adianta muita coisa. Agora o que falta entender é: O que você faz quando 2 objetos produzem o mesmo hash? Como no seguinte exemplo: [code] public static void main(String[] args){
String one = “FB”;
String other = “Ea”;

	System.out.println(one.hashCode());
	System.out.println(other.hashCode());
	
	System.out.println(one.hashCode() == other.hashCode());
	System.out.println(one.equals(other));
}[/code]Nesse caso ambas Strings produzem o mesmo [i]hash[/i], a única maneira de dizer qual é qual, é pelo método [i]equals[/i].

Resumindo, o hash vai te ajudar a agilizar o processo. Colisões de hash são raras, então é possível que só haja um item em cada lugar do array, agora para ter certeza de que o item que você está buscando é o item correto, precisa comparar com equals.

Fez sentido?

A afirmativa abaixo esclarece bastante a relação entre ambos.

“The interface contract for Object requires that if two objects are equal according to equals(), then they must have the same hashCode() value.”

Entretanto, no seu exemplo tenho dois objetos com o mesmo hashCode, mas com equals diferentes. Ficou meio vago sua explicação…

Att,

Thiago Freitas

[quote=thiagolgf]A afirmativa abaixo esclarece bastante a relação entre ambos.

“The interface contract for Object requires that if two objects are equal according to equals(), then they must have the same hashCode() value.”

Entretanto, no seu exemplo tenho dois objetos com o mesmo hashCode, mas com equals diferentes. Ficou meio vago sua explicação…

Att,

Thiago Freitas[/quote]
Você não entendeu a afirmação.

Se você tem 2 objetos que são considerados iguais de acordo com sua implementação de equals, então o valor retornado pelo hashCode de ambos deve ser igual. Agora o oposto não é verdade.

Se você tem 2 objetos que retornam o mesmo valor ao invocar hashCode, isso não quer dizer que ambos serão considerados iguais de acordo com sua implementação de equals.

No meu exemplo eu ilustrei exatamente este caso. Dois objetos diferentes que geram o mesmo hashCode.

Assunto muito complexo… continuo sem entender!

Não existe uma forma de explicar mais palpável… mais simples?

Att,

Thiago Freitas

O que você entendeu por “Tabela de Espalhamento”?

Uma tabela onde os objetos são armazenados de acordo com o seu hashCode.

Att,

Thiago Freitas

Certo, então imagina o seguinte cenário:

Você tem uma tabela dessas populadas com diversos objetos, porém quer que seja retornado um.

Você busca por esse objeto, de acordo com seu hashCode, e ao chegar no seu índice da tabela, vê que existe mais de um objeto ali.

Como você faz pra saber qual objeto é o certo?

Se ambos tem o mesmo hashCode, então preciso verificar através do equals qual é o correto.

Se for isso acredito que tenha entendido.

Att,

Thiago Freitas

Só para dar um exemplo, o Thingol, há alguns anos, pegou uma lista de palavras da língua portuguesa, e verificou quais são as palavras cujo hashcode é o mesmo.

Ou seja, o hashcode bateu, então você tem de usar equals para ver se elas são realmente iguais ou não.

Então o hashCode é apenas um método que retorna um número para critério de comparação e o equals define igualdade (equivalência) de acordo com a sua implementação (necessidade).

Se for isso, está resolvido!

Att,

Thiago Freitas

A regra é simples dois objetos que são equals tem, necessariamente, o mesmo hashcode.
Porém, dois objetos diferentes não tem obrigatoriamente hashCodes diferentes.

Usando a analogia da gaveta de meias. Vamos supor que você defina que vai separar suas meias de acordo com a cor (o hashCode é a cor da meia).
Assim, duas meias completamente pretas devem, necessariamente, ter o mesmo hashCode.

Porém, aquela meia azul petróleo que tua avó te deu pode não se encaixar em nenhuma outra gaveta e, como vc é homem e enxerga azul petróleo como preto (diferente da sua esposa), pode decidir que azul petróleo é preto, e guardar na mesma gaveta (objeto diferente, hashcode igual).

Continua fácil achar meias pretas. E dá um pouco mais de trabalho achar a meia azul petróleo, ou uma meia que seja preta, mas tenha algum tipo de desenho ou tecido específico. Mas ainda assim, é bem melhor do que se você não tivesse guardado as meias separadas por cor.

O que jamais pode acontecer é você ter uma meia preta guardada na gaveta da meia de outra cor. Se isso ocorrer, aí você nunca vai acha-la, já que tem uma gaveta específica para isso.

[RESOLVIDO]

Gostaria de agradecer a todos pelas explicações e paciência com o novato aqui.

Att,

Thiago Freitas

[quote=ViniGodoy]A regra é simples dois objetos que são equals tem, necessariamente, o mesmo hashcode.
Porém, dois objetos diferentes não tem obrigatoriamente hashCodes diferentes.

Usando a analogia da gaveta de meias. Vamos supor que você defina que vai separar suas meias de acordo com a cor (o hashCode é a cor da meia).
Assim, duas meias completamente pretas devem, necessariamente, ter o mesmo hashCode.

Porém, aquela meia azul petróleo que tua avó te deu pode não se encaixar em nenhuma outra gaveta e, como vc é homem e enxerga azul petróleo como preto (diferente da sua esposa), pode decidir que azul petróleo é preto, e guardar na mesma gaveta (objeto diferente, hashcode igual).

Continua fácil achar meias pretas. E dá um pouco mais de trabalho achar a meia azul petróleo, ou uma meia que seja preta, mas tenha algum tipo de desenho ou tecido específico. Mas ainda assim, é bem melhor do que se você não tivesse guardado as meias separadas por cor.

O que jamais pode acontecer é você ter uma meia preta guardada na gaveta da meia de outra cor. Se isso ocorrer, aí você nunca vai acha-la, já que tem uma gaveta específica para isso.[/quote]
Nada como uma resposta didática :slight_smile:

Pensei e pensei em alguma resposta simplificada desse tipo, mas não consegui. Valeu, Vini!

Dá pra ver a diferença entre uma pessoa qualquer ensinando, e um professor ensinando hehehe