2010-02-12 3 views
8

Il semble y avoir un débat en cours sur la question de savoir s'il est sûr de s'appuyer sur l'implémentation actuelle de String.hashCode() car, techniquement, il est garanti par la spécification (Javadoc).Pourquoi Sun a-t-il spécifié l'implémentation de String.hashCode()?

  1. Pourquoi Sun a-t-il spécifié l'implémentation de String.hashCode() dans la spécification?
  2. Pourquoi les développeurs auraient-ils besoin de s'appuyer sur une implémentation spécifique de hashCode()? Pourquoi le soleil a-t-il si peur que le ciel tombera si String.hashCode() est changé dans le futur? (Ceci est probablement expliqué par # 2)

Répondre

8

Une raison de s'appuyer sur l'implémentation spécifique de hashCode() serait si elle est persistante dans une base de données, un fichier ou tout autre support de stockage. Les mauvaises choses (tm) se produiraient si les données étaient relues lorsque l'algorithme de hachage avait changé. Vous pourriez rencontrer des collisions de hachage inattendues, et plus inquiétant, l'impossibilité de trouver quelque chose par son hachage parce que le hachage avait changé entre les données persistantes et "maintenant".

En fait, cette jolie explique beaucoup de point # 3 trop =)

La raison pour le point # 1 pourrait être "pour permettre l'interopérabilité". Si l'implémentation de hashCode est verrouillée, les données peuvent être partagées entre différentes implémentations de Java en toute sécurité. c'est-à-dire que le hachage d'un objet donné sera toujours le même quelle que soit l'implémentation.

+1

Bon point! Je me demande ... auraient-ils pu réaliser la même chose sans verrouiller hashCode()? – Gili

+0

@Gili, non sans ajouter une méthode appelée "implementationAndVersionIndependentHashCode()" ;-) – Rob

+0

@Gili s'ils n'ont pas verrouillé hashCode, comment pourraient-ils être certains que deux machines connectées via RMI pourraient passer des hachages en va-et-vient? Je suppose que vous avez juste à abandonner le concept d'un hachage partagé. –

4

L'implémentation a modifiée depuis la classe String d'origine. Si je me souviens, il était utilisé que chaque caractère 16 (?) A été utilisé dans le hachage pour les chaînes "longues".

Il peut avoir été spécifié pour promouvoir l'interopérabilité de sérialisation entre les versions ultérieures de Java, ou même entre les runtimes de différents fournisseurs. Je suis d'accord, un programmeur ne devrait pas compter sur une implémentation particulière de hashCode() directement, mais le changer pourrait potentiellement casser un lot de collections sérialisées.

+0

La spécification d'origine consistait à lancer une exception 'ArrayOUtOfBoundsException'. :) IIRC, l'implémentation pour les longues chaînes échantillonnées un nombre fixe de caractères, donc O (1) au lieu de O (n) mais un mauvais hachage et en utilisant la chaîne pour tout utile serait (au moins) O (n) de toute façon. –

Questions connexes