Le Mon, 4 May 2009 09:48:22 +0200, Benjamin POUSSIN <poussin@codelutin.com> a écrit :
On Mon, 4 May 2009 05:15:10 +0200 Tony Chemit <chemit@codelutin.com> wrote:
Salut les lutins,
Dans TopiaEntityAbstract, le code de la méthode hashCode me parrait un peu étrange.
/** * On utilise la date de creation comme hash code, cette date ne varie pas * au cours du temps */ @Override public int hashCode() { int result = getTopiaCreateDate().hashCode(); return result; }
Cela transgresse l'ordre naturel des entités. On devrait toujours avoir
a.equals(b) ==> a.hashCode() == b.hashCode()
Oui, et alors c bien le cas ? si a.equals(b) ca veut dire qu'ils ont aussi la meme date de creation. Ou alors ca veut dire que le equals est mal code, mais pas le hashcode
Est-ce qu'on pourrait changer ça en deportant le calcul du hashCode sur celui du topiaId :
@Override public int hashCode() { int hash = 97 * 7; if (topiaId != null) { hash += topiaId.hashCode(); } return hash; }
Il me semble que ca changera rien. Car de toute facon la date de creation est un sous ensemble du topiaId: topiaId => class#date de creation#random
et surtout le hashcode doit etre constant dans le temps, et il me semble que le topiaId, risque de passer de null a quelque chose alors que la date de creation doit toujours etre valide.
Moi ce qui me dérange un peu c'est que le hashCode n'est pas assez fin par rapport au equals. Par contre sur le fait du caractère immuable du hashCode dans le temps, je suis pas trop d'accord, car je pensais qu'un hashCode pouvais varier au cours du temps, dans la javadoc de Object#hashCode, il est bien indiquer que la valeur de la méthode peut varier au cours du temps mais pas au sein de l'execution d'une même application
A verifier tout de meme, mais je pense que ton probleme est ailleurs :)
Ce que je voulais faire c'est pouvoir tester l'égalité d'une clef sur une liste d'entité, pour ce faire je fais ça : boolean answer = true; Set<Integer> hashCodes = new java.util.HashSet<Integer>(); for (Object entry : col) { // construction du hash de la clef d'unicite Integer hash = getUniqueKeyHashCode(entry); if (!hashCodes.contains(hash)) { hashCodes.add(hash); continue; } // une entree avec ce hash a deja ete trouvee // on est donc en violation sur la clef unique answer = false; } et la methode getUniqueKeyHashCode : protected Integer getUniqueKeyHashCode(Object o) { // calcul du hash à la volée HashCodeBuilder builder = new HashCodeBuilder(); for (String key : this.keys) { Object property = getFieldValue(key, o); builder.append(property); } return builder.toHashCode(); } Dans la javadoc de la mé&thode hashCode, y'a écrit : As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. C'est en fait une best-pratice mais c'est pas obligatoire :) et je m'étais basé dessus. Quelqu'un a une idée pour que je réalise un code qui fonctionne tout le temps ?
-- Benjamin -------------------- tél: +33 (0) 2 40 50 29 28 email: poussin@codelutin.com () campagne du ruban ascii http://www.codelutin.com /\ pour les mails en ascii _______________________________________________ Topia-devel mailing list Topia-devel@lists.labs.libre-entreprise.org http://lists.labs.libre-entreprise.org/mailman/listinfo/topia-devel