Je travaille en java depuis quelques années, je code actuellement une
application avec le JDK5 et il se trouve que j'ai eu une petite surprise
cet après midi avec la méthode addAll du HashSet.
Pour moi, cette méthode s'appuie sur equals(Object o) pour dédoublonner
les deux listes à fusionner. Pourtant, en surchargeant uniquement equals
dans les objets que contient ma liste, ça ne fonctionnait pas, et après
avoir farfouillé un peu sur la toile, j'ai découvert qu'il fallait aussi
surcharger hashCode() pour que cela fonctionne.
Est ce une nouveauté de ce JDK, ou bien ma mémoire est défaillante ?
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Nico
"Symon" a écrit dans le message de news:d2emt5$82u$
Salut à vous,
Je travaille en java depuis quelques années, je code actuellement une application avec le JDK5 et il se trouve que j'ai eu une petite surprise cet après midi avec la méthode addAll du HashSet.
Pour moi, cette méthode s'appuie sur equals(Object o) pour dédoublonner les deux listes à fusionner. Pourtant, en surchargeant uniquement equals dans les objets que contient ma liste, ça ne fonctionnait pas, et après avoir farfouillé un peu sur la toile, j'ai découvert qu'il fallait aussi surcharger hashCode() pour que cela fonctionne.
Est ce une nouveauté de ce JDK, ou bien ma mémoire est défaillante ?
Pour moi, c'est tout à fait normal. Un HashSet ou un HashMap commence par utiliser hashCode() pour savoir dans quelle partie de la table de hachage il doit chercher l'objet. Ensuite il utilise la méthode equals() sur les objets qui sont dans cette partie de la table de hachage pour finir la recherche. Si il n'utilisait que equals(), il faudrait parcourir toute la table pour rechercher un objet, c'est à dire perdre complètement l'intérêt de HashSet.
Nicolas
"Symon" <symon@tatouage.fr> a écrit dans le message de
news:d2emt5$82u$1@aphrodite.grec.isp.9tel.net...
Salut à vous,
Je travaille en java depuis quelques années, je code actuellement une
application avec le JDK5 et il se trouve que j'ai eu une petite surprise
cet après midi avec la méthode addAll du HashSet.
Pour moi, cette méthode s'appuie sur equals(Object o) pour dédoublonner
les deux listes à fusionner. Pourtant, en surchargeant uniquement equals
dans les objets que contient ma liste, ça ne fonctionnait pas, et après
avoir farfouillé un peu sur la toile, j'ai découvert qu'il fallait aussi
surcharger hashCode() pour que cela fonctionne.
Est ce une nouveauté de ce JDK, ou bien ma mémoire est défaillante ?
Pour moi, c'est tout à fait normal.
Un HashSet ou un HashMap commence par utiliser hashCode() pour savoir dans
quelle partie de la table de hachage il doit chercher l'objet. Ensuite il
utilise la méthode equals() sur les objets qui sont dans cette partie de la
table de hachage pour finir la recherche.
Si il n'utilisait que equals(), il faudrait parcourir toute la table pour
rechercher un objet, c'est à dire perdre complètement l'intérêt de HashSet.
"Symon" a écrit dans le message de news:d2emt5$82u$
Salut à vous,
Je travaille en java depuis quelques années, je code actuellement une application avec le JDK5 et il se trouve que j'ai eu une petite surprise cet après midi avec la méthode addAll du HashSet.
Pour moi, cette méthode s'appuie sur equals(Object o) pour dédoublonner les deux listes à fusionner. Pourtant, en surchargeant uniquement equals dans les objets que contient ma liste, ça ne fonctionnait pas, et après avoir farfouillé un peu sur la toile, j'ai découvert qu'il fallait aussi surcharger hashCode() pour que cela fonctionne.
Est ce une nouveauté de ce JDK, ou bien ma mémoire est défaillante ?
Pour moi, c'est tout à fait normal. Un HashSet ou un HashMap commence par utiliser hashCode() pour savoir dans quelle partie de la table de hachage il doit chercher l'objet. Ensuite il utilise la méthode equals() sur les objets qui sont dans cette partie de la table de hachage pour finir la recherche. Si il n'utilisait que equals(), il faudrait parcourir toute la table pour rechercher un objet, c'est à dire perdre complètement l'intérêt de HashSet.
Nicolas
Symon
Je me disais bien que j'avais omis quelque chose dans ma réflexion (par méconnaissance du fonctionnement interne de l'objet HashSet)...
Merci pour cette clarification ! Je vais creuser un peu la notion de hash code, j'avoue ne pas connaitre grand chose sur la façon dont il est généré, ni ou il est utilisé !
Symon
Nico wrote:
Pour moi, c'est tout à fait normal. Un HashSet ou un HashMap commence par utiliser hashCode() pour savoir dans quelle partie de la table de hachage il doit chercher l'objet. Ensuite il utilise la méthode equals() sur les objets qui sont dans cette partie de la table de hachage pour finir la recherche. Si il n'utilisait que equals(), il faudrait parcourir toute la table pour rechercher un objet, c'est à dire perdre complètement l'intérêt de HashSet.
Nicolas
Je me disais bien que j'avais omis quelque chose dans ma réflexion (par
méconnaissance du fonctionnement interne de l'objet HashSet)...
Merci pour cette clarification ! Je vais creuser un peu la notion de
hash code, j'avoue ne pas connaitre grand chose sur la façon dont il est
généré, ni ou il est utilisé !
Symon
Nico wrote:
Pour moi, c'est tout à fait normal.
Un HashSet ou un HashMap commence par utiliser hashCode() pour savoir dans
quelle partie de la table de hachage il doit chercher l'objet. Ensuite il
utilise la méthode equals() sur les objets qui sont dans cette partie de la
table de hachage pour finir la recherche.
Si il n'utilisait que equals(), il faudrait parcourir toute la table pour
rechercher un objet, c'est à dire perdre complètement l'intérêt de HashSet.
Je me disais bien que j'avais omis quelque chose dans ma réflexion (par méconnaissance du fonctionnement interne de l'objet HashSet)...
Merci pour cette clarification ! Je vais creuser un peu la notion de hash code, j'avoue ne pas connaitre grand chose sur la façon dont il est généré, ni ou il est utilisé !
Symon
Nico wrote:
Pour moi, c'est tout à fait normal. Un HashSet ou un HashMap commence par utiliser hashCode() pour savoir dans quelle partie de la table de hachage il doit chercher l'objet. Ensuite il utilise la méthode equals() sur les objets qui sont dans cette partie de la table de hachage pour finir la recherche. Si il n'utilisait que equals(), il faudrait parcourir toute la table pour rechercher un objet, c'est à dire perdre complètement l'intérêt de HashSet.
Nicolas
Jocelyn
Salut, D'une manière générale, il faut redéfinir hashcode() à chaque fois que tu redéfinis equals(). Sinon tu risques de violer le contrat imposé par la classe Object qui se compose de 3 points: - la méthode hashcode d'un objet doit renvoyer la meme valeur lors d'appels successifs, tant qu'aucune des infos utilisées dans equals n'est modifiée. - si 2 objets sont considérés comme égaux par equals, hashcode doit renvoyer la meme valeur pour ces 2 objets. - il n'est pas imposé (bien que souhaitable pour les performances des tables de hachage) que 2 objets considérés comme différents par equals renvoient des hashcode differents.
Note que je n'invente rien (tout ca est dans la doc) et que tu peux en savoir plus en consultant l'excellent livre Java Efficace. Il explique notamment comment construire une fonction de hashcode qui tienne la route. Tu peux peut-etre trouver ca sur le net aussi :)
Bon courage !
Salut,
D'une manière générale, il faut redéfinir hashcode() à chaque fois
que tu redéfinis equals(). Sinon tu risques de violer le contrat
imposé par la classe Object qui se compose de 3 points:
- la méthode hashcode d'un objet doit renvoyer la meme valeur lors
d'appels successifs, tant qu'aucune des infos utilisées dans equals
n'est modifiée.
- si 2 objets sont considérés comme égaux par equals, hashcode doit
renvoyer la meme valeur pour ces 2 objets.
- il n'est pas imposé (bien que souhaitable pour les performances des
tables de hachage) que 2 objets considérés comme différents par equals
renvoient des hashcode differents.
Note que je n'invente rien (tout ca est dans la doc) et que tu peux en
savoir plus en consultant l'excellent livre Java Efficace. Il explique
notamment comment construire une fonction de hashcode qui tienne la
route. Tu peux peut-etre trouver ca sur le net aussi :)
Salut, D'une manière générale, il faut redéfinir hashcode() à chaque fois que tu redéfinis equals(). Sinon tu risques de violer le contrat imposé par la classe Object qui se compose de 3 points: - la méthode hashcode d'un objet doit renvoyer la meme valeur lors d'appels successifs, tant qu'aucune des infos utilisées dans equals n'est modifiée. - si 2 objets sont considérés comme égaux par equals, hashcode doit renvoyer la meme valeur pour ces 2 objets. - il n'est pas imposé (bien que souhaitable pour les performances des tables de hachage) que 2 objets considérés comme différents par equals renvoient des hashcode differents.
Note que je n'invente rien (tout ca est dans la doc) et que tu peux en savoir plus en consultant l'excellent livre Java Efficace. Il explique notamment comment construire une fonction de hashcode qui tienne la route. Tu peux peut-etre trouver ca sur le net aussi :)
Bon courage !
Kupee
Jocelyn wrote:
Note que je n'invente rien (tout ca est dans la doc) et que tu peux en savoir plus en consultant l'excellent livre Java Efficace. Il explique notamment comment construire une fonction de hashcode qui tienne la route. Tu peux peut-etre trouver ca sur le net aussi :)
A ce sujet d'ailleurs il y a la lib common-lang de jakarta qui a un générateur de Hashcode qui semble etre basé sur le bouquin dont tu parles : http://jakarta.apache.org/commons/lang/api/org/apache/commons/lang/builder/HashCodeBuilder.html
Jocelyn wrote:
Note que je n'invente rien (tout ca est dans la doc) et que tu peux en
savoir plus en consultant l'excellent livre Java Efficace. Il explique
notamment comment construire une fonction de hashcode qui tienne la
route. Tu peux peut-etre trouver ca sur le net aussi :)
A ce sujet d'ailleurs il y a la lib common-lang de jakarta qui a un
générateur de Hashcode qui semble etre basé sur le bouquin dont tu
parles :
http://jakarta.apache.org/commons/lang/api/org/apache/commons/lang/builder/HashCodeBuilder.html
Note que je n'invente rien (tout ca est dans la doc) et que tu peux en savoir plus en consultant l'excellent livre Java Efficace. Il explique notamment comment construire une fonction de hashcode qui tienne la route. Tu peux peut-etre trouver ca sur le net aussi :)
A ce sujet d'ailleurs il y a la lib common-lang de jakarta qui a un générateur de Hashcode qui semble etre basé sur le bouquin dont tu parles : http://jakarta.apache.org/commons/lang/api/org/apache/commons/lang/builder/HashCodeBuilder.html