| Autor |
Mensagem |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 16/02/2010 15:43:14
|
douglas_vidotto
JavaTeenager
![[Avatar]](/images/avatar/2b37aae16df6fc89dd503c3b2dfbf165.png)
Membro desde: 12/08/2008 15:43:18
Mensagens: 195
Offline
|
Olá pessoal. Eu estou estudando para a certificação pelo livro da Kathy Sierra. Estou no capítulo sobre Collections e Genéricos. Cheguei na parte em que é explicado o funcionamento da interface Map, mas não consegui entender direito o seu funcionamento. Me deu um nó na cabeça. Bom, vou postar o pedaço do código da minha dúvida e tentar explicar o que eu não entendi.
Primeiramente há uma classe Dog que implementa de forma correta os métodos equals() e hashCode():
Depois a classe que usa o Map:
A saída desse código é: Dog Key, null, Dog Key, null.
Ok, vamos lá. A primeira saída é fácil de entender. Afinal, foi criada uma chave que é um objeto Dog para o valor String "Dog Key". Minha dúvida começa a partir do segundo get. O código muda o nome do Dog de "clover" para "magnolia" e usa o próprio objeto para buscar o valor "Dog Key". Mesmo que o nome tenha mudado, e consequentemente o código hash da chave também, se o próprio objeto é a chave, por que ele não conseguiu achar "Dog Key"? Pois a chave é o objeto referenciado por d1 e o método get é chamado usando-se o d1. Com isso eu imaginei: "Bom, ele deve ter mantido o código hashing de quando o valor foi inserido junto com a chave na primeira chamada a put() e essa chave é 6, diferente de 'magnolia' que é 8' ". Mas se fosse dessa maneira que pensei, para mim o último get deveria retornar o valor correto "Dog Key" e não null. Pois como estou passando um objeto com o nome "clover" e na hora da inserção chave/valor, o objeto era "clover", ele deveria retornar o valor correto. Mas não é desse jeito. Ele passou um objeto Dog novo e o comparou com o objeto dog que é a chave, o qual é referenciado por d1. Como possuem valores diferentes para nome, não passam no teste do equals(). Mas por que no caso de "magnolia" não deu certo se a própria chave é o d1? Não sei se fui muito compreensivo na dúvida, mas...
Agradeço a ajuda e desculpem pelo longo texto.
Abraços!
This message was edited 1 time. Last update was at 16/02/2010 22:20:24
|
|
|
 |
|
|
![[Post New]](/templates/default/images/icon_minipost_new.gif) 16/02/2010 19:09:21
|
pmlm
GUJ Master
Membro desde: 20/04/2009 12:20:07
Mensagens: 1199
Localização: Portugal
Offline
|
douglas_vidotto wrote:
A comparação de Strings não deve ser feita com ==
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 16/02/2010 20:08:39
|
TiagoTC
JavaTeenager
Membro desde: 09/02/2008 01:12:58
Mensagens: 189
Offline
|
A observação do pmlm está correta, mas acho que não esclarece sua dúvida. Supondo que você implemente o equals corretamente assim:
Não sei se entendi direito a sua dúvida, mas o que ocorre é o seguinte.
Aqui o hash de d1 é calculado. Como d1 é na verdade um Dog, o Java vai usar a implementação hash e equals da sua classe Dog. Ao dar o put acima, o hash é calculado. Pela implementação da sua classe Dog o hash acaba usando simplesmente a implementação hash da classe String. Assim, o hash do atributo "name" é calculado. Vamos supor (só para ficar mais fácil) que esse hash tem 10 "recipientes" e que, ao calcular esse primeiro hash ("clover") tal hash dê 2. Logo, d1 será colocado no "recipiente" 2.
Aqui vc mudou o atributo do objeto d1 para "magnolia", porém, d1 continua no "recipiente" 2 !!! Ao fazer m.get(d1), o hash é calculado, mas dessa vez, é calculado com relação à String "magnolia". Vamos supor que tal hash dê 6. Assim, o Java vai sair percorrendo o "recipiente" 6 e comparando um a um com o método equals até ver se acha algum objeto igual (esse igual é sempre com relação ao método equals) ao passado no parêmetro get. Porém, não há nenhum objeto no "recipiente" 6! (Apenas no 2). Logo, ele não acha nada e retorna null.
Aqui vc mudou o parâmetro novamente para "clover". O objeto d1 continua no "recipiente" 2. Na chamada do get, ele vai usar o hashcode novamente, mas dessa vez o hashcode vai dar 2 também (pois é a mesma String e o hashcode implementado por você apenas usa essa String). Assim, o Java vai sair comparando tudo que estiver no "recipiente" 2 com o método equals. Agora sim, como d1 está ali no recipiente 2 (e d1.name possui a String "clover"), ele vai encontrá-lo e, logo, retornar o valor correspondente (no caso, "Dog key").
Aqui vai acontecer a mesma coisa do passo anterior. Porém, na hora do Java comparar com o método equals no "recipiente" 2, ele não vai encontrar nada (pois o atrivuto "name" de d1 não é mais "clover" e sim "arthur"). Logo a comparação com equals falha e retorna null (não achou nada).
Acho que era essa a sua dúvida. Se não for, poste novamente que eu tento ajuda de outra forma.
|
Pérola: "Nunca coloque seu celular em um forno de microondas, pois isso faz com que a bateria exploda" - Manuais de telefones celulares |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 16/02/2010 22:19:08
|
douglas_vidotto
JavaTeenager
![[Avatar]](/images/avatar/2b37aae16df6fc89dd503c3b2dfbf165.png)
Membro desde: 12/08/2008 15:43:18
Mensagens: 195
Offline
|
Fala Tiago..blz? Minha dúvida era exatamente essa e você conseguiu esclarecer muito bem!! Muito obrigado. Quanto ao código em que ele faz a comparação de Strings com ==, realmente está inadequado. Mas eu copiei exatamente como estava no livro (tirando só os pedaços que não faziam parte da dúvida). Mas confesso que nem tinha prestado atenção nisso, hehehehe.
|
|
|
 |
|
|
|
|