ae pessoal no cap 7 do livro da kathy ela fala que, objetos iguais devem ter o hashing iguais… bom teoricamente ela explicou bem… mais nao explicou a implementação do hashCode() ou seja como cumprir com o contrato… fiquei nessa duvida veja na sintaxe abaixo…
classHas{privateintn;Has(intz){n=z;}publicintgetInt(){returnn;}//subscrevendo para saber se os objetos sao equivalentespublicbooleanequals(Objecto){if((oinstanceofHas)&&(((Has)o).getInt()==this.n)){returntrue;}else{returnfalse;}}publicstaticvoidmain(Stringagrs[]){Hash=newHas(9);Hash1=newHas(9);System.out.println(h.equals(h1));}}
porem queria saber de os codigos dos objetos sao iguais… implementado o hashCode() mais nem sei por onde ir… quem puder dar esse help
Camilo, não sei se entendi a sua duvida, mas quando sobrescrevemos o equals, é seguro sobrescrever o hashcode tbem, para que os mesmos objetos tenham hashcode iguais, para saber o hascode dos objetos basta fazer isso:
objeto.hashcode();
Espero ter ajudado em alguma coisa…
ViniGodoy
Existem várias formas de se implementar um hashcode. Uma delas, sugerida no livro Effective Java, capítulo 3, item 8, que pode ser lido nesse link (eu recomendo fortemente que você leia o livro todo): http://java.sun.com/developer/Books/effectivejava/Chapter3.pdf
Ele diz o seguinte:
Armazene algum valor constante, diferente de zero (por exemplo, 17);
Pegue todos os atributos relevantes para sua classe (geralmente são aqueles usados no equals, para saber se o objeto é igual ao outro). Para cada um deles faça, calcule um hashcode inteiro c:
i. Se o campo é boolean, compute (f ? 0 : 1);
ii. Se o campo é um byte, char, short ou int, compute (int)f;
iii. Se o campo é um long, compute (int)(f ^ (f >>> 32));
iv. Se o campo é um float, compute Float.floatToBits(f);
v. Se o campo é um double, compute Double.doubleToLongBits(f) e use o hash para longs no resultado descrito no passo iii.
vi. Se o campo é um objeto, e ele é nulo, compute 0. Caso contrário, use o hashcode desse objeto. Se uma comparação mais profunda é necessária, crie uma "representação canônica" para essa classe, e use o hash dessa representação.
vii. Se o campo é um array, trate-o como se cada elemento fosse um campo separado.
Combine o hashcode c calculado para cada elemento num resultado como descrito:
result = 37 * result + c;
Retorne o resultado.
No caso de sua classe, você poderia simplesmente retornar n. Afinal ele é o único atributo e define a igualdade. Entretanto, só para exemplificar, usando o algoritmo descrito acima, teríamos:
publicinthashCode(){intresult=17;result=37*result+n;//n é um int, se enquadra na regra ii.returnresult;}
Supondo que você acrescentasse ainda um outro atributo s, do tipo String, seu código ficaria assim:
publicinthashCode(){intresult=17;result=37*result+n;//n é um int, se enquadra na regra ii.result=37*result+s==null?0:s.hashCode();//É um objeto, regra vi.returnresult;}
Esse algoritmo não é o estado da arte de um hashcode, mas é suficientemente rápido, fácil de implementar e bastante confiável.
Por fim, o eclipse gera automaticamente esse algoritmo, para todos os campos de sua classe, se você usar a opção source->generate hashcode and equals.
Novamente, dê uma lida no capítulo que eu coloquei o link, para mais considerações e exemplos do uso de hashcode.
Alguns meses depois, postei no GUJ uma classe que implementa esse algorítmo:
LPJava
ae… galera valeu…mais fiquei na duvida agora veja como ficou meu codigo:
classHas{privateintn;Has(intz){n=z;}publicintgetInt(){returnn;}//subscrevendo para saber se os objetos sao equivalentespublicbooleanequals(Objecto){if((oinstanceofHas)&&(((Has)o).getInt()==this.n)){returntrue;}else{returnfalse;}}publicstaticvoidmain(Stringagrs[]){Hash=newHas(9);Hash1=newHas(9);System.out.println(h.equals(h1));System.out.println(h.hashCode());}}
ele imprime o codigo hashinh mais se eu mandar imprimir o h1.hashCode() pq o valor eh diferente ja que os objetos sao equivalentes?
Deh
Pela Api,
hashCode() da java.lang.Object é native, e ela dá o valor ‘int’ pegando o endereço do objeto para um int… dois objetos diferentes, dois lugares diferentes da memória…
por isso o hashCode() resulta em valores diferentes… você deveria sobreescrever o “public int hashCode()” para ter o comportamento correto. =]
ViniGodoy
Camilo, assim como você fez com o equals, você deve sobrescrever o método hashcode. Aliás, o título do capítulo do Effective java que te sugeri já diz tudo: “Sempre sobrescreva o hashCode se você sobrescrever o equals”.
O método hashcode default não tem como adivinhar que você sobrescreveu o equals. E mesmo que tivesse, ele não teria como adivinhar que regra você colocou lá dentro.
No meu post anterior eu te sugeri um algoritmo mais ou menos genérico de como fazer o seu próprio método hashCode, o mesmo usado no Effective Java.
No caso da sua classe, você pode muda-la para:
classHas{privateintn;Has(intz){n=z;}publicintgetInt(){returnn;}//subscrevendo para saber se os objetos sao equivalentespublicbooleanequals(Objecto){if((oinstanceofHas)&&(((Has)o).getInt()==this.n)){returntrue;}else{returnfalse;}}//sobrescrevendo para garantir o contrato do hash, para o novo equals//Estou usando o algoritmo descrito no post anterior, mas nesse caso, //você poderia fazer simplesmente return n.publicinthashCode(){intresult=17;result=37*result+n;//n é um int, se enquadra na regra ii.returnresult;}publicstaticvoidmain(Stringagrs[]){Hash=newHas(9);Hash1=newHas(9);System.out.println(h.equals(h1));System.out.println(h.hashCode()+"="+h1.hashCode());}}
LPJava
po galera vaelu entao… conseguir entender… so para resumir… eu posso definir o codigo do meu hashCode() caso venha subscrever ele certo? com as explicacoes de vcs implementei o codigo abaixo:
classHas{privateintn;Has(intz){n=z;}publicintgetInt(){returnn;}//subscrevendo para saber se os objetos sao equivalentespublicbooleanequals(Objecto){if((oinstanceofHas)&&(((Has)o).getInt()==this.n)){returntrue;}else{returnfalse;}}//implementacao do hashCode()publicinthashCode(){returnn^17;}publicstaticvoidmain(Stringagrs[]){Hash=newHas(999);Hash1=newHas(999);System.out.println(h.equals(h1));System.out.println(h.hashCode());System.out.println(h1.hashCode());}}/* implementei meu hashCode quando os objetos sao diferentes eles return ovalor do codigo hashing diferente*/
flw! mesmo… vinny vc anda sumido heim…trabalhando muito pelo visto!!