2010-02-12 17 views
8

Parece que hay un debate en curso acerca de si es seguro confiar en la implementación actual del String.hashCode() porque, técnicamente hablando, está garantizado por la especificación (Javadoc).¿Por qué Sun especificó la implementación de String.hashCode()?

  1. ¿Por qué Sun especificó la implementación de String.hashCode() en la especificación?
  2. ¿Por qué los desarrolladores alguna vez necesitarían confiar en una implementación específica de hashCode()?
  3. ¿Por qué el Sol tiene tanto miedo de que el cielo se caiga si se cambia String.hashCode() en el futuro? (Esto probablemente se explicará por # 2)

Respuesta

8

Una razón para confiar en la implementación específica de hashCode() sería si alguna vez se persiste en una base de datos, archivo o cualquier otro medio de almacenamiento. Las cosas malas (tm) ocurrirían si los datos se leyeran de nuevo cuando el algoritmo hash ha cambiado. Puede encontrar colisiones hash inesperadas y, lo que es más preocupante, la imposibilidad de encontrar algo mediante su hash porque el hash ha cambiado entre la persistencia de los datos y "ahora".

De hecho, que explica más o menos el punto # 3 demasiado =)

La razón para el punto # 1 podría ser "para permitir la interoperabilidad". Si la implementación de hashCode está bloqueada, los datos se pueden compartir entre diferentes implementaciones de Java con bastante seguridad. es decir, el hash de un objeto dado siempre será el mismo independientemente de la implementación.

+1

¡Buen punto! Me pregunto ... ¿podrían haber logrado lo mismo sin bloquear hashCode()? – Gili

+0

@Gili, no sin añadir un método llamado "implementationAndVersionIndependentHashCode()" ;-) – Rob

+0

@Gili si no cerraba abajo hashCode, ¿cómo podían estar seguros de que dos máquinas conectadas a través de RMI podían pasar los hashes de ida y vuelta? Supongo que solo debes renunciar al concepto de hash compartido. –

4

La implementación ha cambiado desde la clase original String. Si recuerdo, solía ser que solo se utilizaba cada 16º (?) Carácter en el hash para cadenas "largas".

puede haber sido especificado para promover la interoperabilidad serialización entre las versiones posteriores de Java, o incluso entre los tiempos de ejecución de diferentes proveedores. Estoy de acuerdo, un programador no debe confiar en una implementación particular de hashCode() directamente, pero cambiarla podría potencialmente romper un lote de colecciones serializadas.

+0

La especificación original era arrojar un 'ArrayOUtOfBoundsException'. :) IIRC, la implementación de cadenas largas muestreó un número fijo de caracteres, por lo que O (1) en lugar de O (n) pero un mal hash y usar la cadena para cualquier cosa útil sería (al menos) O (n) de todos modos. –

Cuestiones relacionadas