Está faltando compreensão básica sobre para que servem o hashcode e o equals.
Os principais motivos no seu uso em sets é que queremos evitar inserir valores duplicados, e porque queremos rapidamente saber se um determinado objeto já consta de um set (digamos, usando um método contains() ) Digamos que você tenta fazer: meuSet.contains(x) ou meuSet.add(x) O que significa testar se um objeto "x" está no set? Lembre-se que o set é um conjunto de referências. Pode ser que x aponte para um mesmo objeto que esteja sendo apontado por uma referência que conste do set. Nesse caso, claramente x "está no set". E pode ser que x aponte para um objeto que NÃO esteja sendo apontado por nenhuma referência contida no set, MAS que seja "igual", para fins da aplicação, a outro objeto que esteja sendo apontado por alguma referência do set. Por exemplo, x aponta para um objeto String contendo a palavra "UFRJ", e alguma referência dentro do set aponta para outro objeto distinto, mas contendo a mesma palavra "UFRJ". E aí? O set "contém x" ou não? Se fossemos ser rigorosos, no segundo caso x não estaria no set. Mas, para todos os efeitos "práticos", o que queremos saber é se o set contém a palavra "UFRJ". Aí é que entra o método equals(). O teste de x pertencer a um set, em Java, é feito perguntando se alguma referência que já esteja no set é "equals(x)". Na classe Object, equals() é sinônimo de "==", mas na classe String, por exemplo, esse método é sobrescrito para retornar true sempre que os caracteres dos objetos comparados forem os mesmos e na mesma ordem. Por causa disso, duas strings distintas, mas com as mesmas letras, são consideradas "o mesmo" objeto, para fins de teste de inclusão em sets. Mas isso tudo não é suficiente para garantir que duas strings "iguais" não existirão em um set. No caso dos hashsets, a busca por um objeto em um set usa a seguinte estratégia: aplica-se um algoritmo de hash ao objeto que esteja sendo procurado. O algoritmo retorna um inteiro, que é o hashcode. Esse inteiro é usado para localizar uma única sub-região do set. Nessa sub-região é que se procura por alguma referência que seja "equals()" ao objeto procurado. Se for encontrada lá uma referência que seja "equals()", o objeto está no set e, se não for encontrada, o objeto não está no set. Ponto final, as demais regiões do set não são pesquisadas. Isso é feito assim para se conseguir boa eficiência na busca em sets muito grandes. Como podemos garantir que não será preciso pesquisar nas demais regiões do set? Simplesmente garantindo que, se algum objeto for "equals()" a qualquer elemento que já esteja no set, o seu hashcode será o mesmo dele, mesmo que sejam objetos distintos. Portanto, para o HashSet funcionar, a classe de seus elementos deve implementar tanto um metodo equals() apropriado, como um sobrescrever o método int hashCode() de forma que seja compatível com esse equals(), ou seja, que retorne sempre o mesmo inteiro para dois objetos que sejam "equals()" entre si. Imagine o que pode ocorrer se você não fizer um método hashCode() adequado: se dois objetos "equals()" puderem gerar hashcodes diferentes, na hora de tentarmos incluir o segundo no set ele será procurado em uma sub-região dferente da do primeiro, e não sendo encontrado, um elemento duplicado será incluído no set. Notem que para usar TreeSet isso não é importante, porque o TreeSet usa outra estratégia para busca eficiente. No caso do TreeSet, além do equals(), é necessário ter um método comparador que seja compatível com esse equals(), ou seja, para dois elementos que sejam "equals()", o método deve retornar zero. Uma última observação importante: estamos sempre falando em sobrescrever métodos equals() com assinatura: boolean equals(Object obj) E NÃO com a assinatura: boolean equals (<tipo do set> elem) abraços! Jonathan 2008/10/13 Peter <[EMAIL PROTECTED]> > Na verdade, de acordo com > http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Object.html#hashCode()<http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Object.html#hashCode%28%29> > se vc não muda seu hashcode quando mudar seu equals, sua classe está errada > pq um método não funciona como deveria. > > (na verdade vc quebrou a conformidade de tipo, mas isto é assunto para > depois de comp 2) > > Além disto, não construimos uma classe pensando se vamos ou não utilizá-la > num hashset ou hashmap, até pq o ideal é que a gente tente sempre reutilizar > as coisas. Então, ao fazer o equals, faça tb o hashcode correto. Nunca se > sabe o que vem pela frente. > > Em tempo: no eclipse, com o botão direito na classe e utilizando o menu > "source" (eu acho...) tem a opção de gerar o par equals e hashcode... basta > escolher os campos que participarão da comparação. Ele já escreve um > hashcode de baixa colisão tb. > > Abraço! > > Peter P. Lupo > Undergraduating in Computer Science DCC/UFRJ > Sun Certified Java Associatehttp://pplupo.googlepages.com/ > Cell. +55 (21) 81742487 > > > > Raphael Duarte Paiva wrote: > > Nem sempre, só quando formos utilizar hashes, como um HashMap, por exemplo. > > O motivo é que o hash deve ser único para cada objeto, então como o equals > diferencia um objeto dos outros em uma comparação, o hash deve ser > condizente com o equals. Por exemplo: se em sua aplicação, se duas pessoas > tem o mesmo nome, elas são necessariamente a mesma pessoa, elas devem ter o > mesmo hash e se eu fizer pessoa1.equals(pessoa2), deve retornar true. > > Resumindo, o hash é como uma identidade de um objeto. Se dois objetos são > iguais, devem ter o mesmo hash, assim como o equals entre os dois deve > retornar true. > > > []'s > > On Mon, Oct 13, 2008 at 17:41, Gustavo Cury <[EMAIL PROTECTED]>wrote: > >> Porque sempre devemos sobrescrever o hashcode quando sobrescrevemos o >> equals ? >> >> Obrigado >> Gustavo Cury >> >> ------------------------------ >> Instale a Barra de Ferramentas com Desktop Search e ganhe EMOTICONS para o >> Messenger! É GRÁTIS! <http://www.msn.com.br/emoticonpack> >> >> > > > -- > Abraços > Raphael Duarte Paiva > Graduando em Ciência da Computação > > > > > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Comp 2 - Geral" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/comp2-geral?hl=en -~----------~----~----~----~------~----~------~--~---
