145 votes

Cohérence des hashCode() sur une chaîne de Java

Le hashCode de la valeur de Java Chaîne est calculé comme (Chaîne de caractères.hashCode()):

s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]

Existe-il des circonstances (dire JVM version, fournisseur, etc.) en vertu de laquelle l'expression suivante à false?

boolean expression = "This is a Java string".hashCode() == 586653468

Mise à jour #1: Si vous prétendez que la réponse est "oui, il y a de telles circonstances" - alors s'il vous plaît donner un exemple concret de lorsque "Cela est un Java string".hashCode() != 586653468. Essayez d'être aussi précis/concret que possible.

Mise à jour #2: Nous savons tous que le fait de compter sur les détails de mise en œuvre de hashCode() est mauvais en général. Cependant, je parle précisément de la Chaîne.hashCode() - veuillez donc garder la réponse ciblée à la Chaîne.hashCode(). Objet.hashCode() est totalement hors de propos dans le contexte de cette question.

107voto

Jon Skeet Points 692016

Je peux voir que la documentation d'aussi loin que Java 1.2.

C'est vrai qu' en général, vous ne devriez pas compter sur un code de hachage de la mise en œuvre reste la même, maintenant c'est le comportement documenté pour java.lang.String, de sorte qu'un changement il correspond à la rupture de contrats existants.

Dans la mesure du possible, vous ne devriez pas compter sur les codes de hachage en restant la même dans les deux versions, etc - mais dans mon esprit, java.lang.String est un cas particulier tout simplement parce que l'algorithme a été spécifié... aussi longtemps que vous êtes prêt à abandonner la compatibilité avec les versions avant que l'algorithme a été spécifié, bien sûr.

20voto

ReneS Points 1526

J'ai trouvé quelque chose à propos de JDK 1.0 et 1.1 et >= 1.2:

Dans le JDK 1.0.x et 1.1.x le hashCode la fonction de longues Chaînes travaillé par l'échantillonnage de chaque nième caractère. Cette assez bien garanti que vous auriez de nombreuses Chaînes de hachage à la même valeur, ce qui ralentit la table de hachage de recherche. Dans le JDK 1.2 la fonction a été amélioré afin de multiplier le résultat jusqu'à présent, d'ici le 31 puis ajouter le suivant personnage dans la séquence. C'est un peu plus lent, mais il est beaucoup mieux en évitant les collisions. Source: http://mindprod.com/jgloss/hashcode.html

Quelque chose de différent, parce que vous semblez avoir besoin d'un nombre: Comment sur l'utilisation de CRC32, MD5 ou au lieu de hashcode et vous êtes bon pour go - pas de discussions et pas de soucis du tout...

8voto

Martin OConnor Points 1877

Vous ne devriez pas compter sur un code de hachage étant égal à une valeur spécifique. Juste qu'il sera de retour à des résultats cohérents au sein de la même exécution. L'API docs dire la chose suivante :

Les conditions générales du contrat de hashCode est:

  • Chaque fois qu'elle est invoquée sur le même objet plus d'une fois lors d'une exécution d'une application Java, la méthode hashCode doit constamment revenir par le même entier, a fourni aucune information utilisée dans les égaux des comparaisons sur l'objet est modifié. Cet entier n'a pas besoin de rester cohérent à partir d'une exécution d'une application à une autre exécution de la même application.

MODIFIER Depuis la javadoc de la Chaîne.hashCode() spécifie comment une Chaîne de code de hachage de l'est calculée, toute violation de ce qui violerait le public spécification de l'API.

3voto

ReneS Points 1526

Juste pour répondre à votre question et ne pas de poursuivre les discussions. La mise en œuvre de l’Apache Harmony JDK semble être d’utiliser un algorithme différent, au moins, il semble totalement différente :

Sun JDK

Harmonie de Apache

N’hésitez pas à vérifier vous-même...

3voto

Brian Agnew Points 143181

Un autre (!) question à vous inquiéter, c'est le possible changement de mise en œuvre entre le début/la fin de versions de Java. Je ne crois pas que les détails de mise en œuvre sont définies dans la pierre, et donc potentiellement une mise à niveau vers une future version de Java pourrait causer des problèmes.

Ligne du bas est, je ne voudrais pas compter sur la mise en œuvre de l' hashCode().

Peut-être que vous pouvez mettre en évidence ce problème que vous êtes en train d'essayer de résoudre à l'aide de ce mécanisme, et qui va mettre en lumière une approche plus appropriée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X