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():
import java.util.*;
class Dog{
public Dog(String n) { name = n; }
public String name;
public boolean equals(Object o){
if((o instanceof Dog) && ((Dog)o).name == name){
return true;
} else{
return false;
}
}
public int hashCode() { return name.length(); }
}
Depois a classe que usa o Map:
class MapTest{
public static void main(String[] args){
Map<Object, Object> m = new HashMap<Object, Object>();
Dog d1 = new Dog("clover");
m.put(d1, "Dog Key");
System.out.println(m.get(d1));
d1.name = "magnolia";
System.out.println(m.get(d1));
d1.name = "clover";
System.out.println(m.get(new Dog("clover")));
d1.name="arthur";
System.out.println(m.get(new Dog("clover")));
}
}
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!