2009-10-04 18 views
5

¿Se requiere que la salida de Object.hashCode() sea la misma en todas las implementaciones de JVM para el mismo objeto?Java, Object.hashCode() ¿resultado constante en todas las JVM/Sistemas?

Por ejemplo, si "test".hashCode() devuelve 1 en 1.4, podría devolver 2 funcionando en 1.6. ¿O qué pasaría si los sistemas operativos fueran diferentes o existiera una arquitectura de procesador diferente entre las instancias?

Respuesta

14

No. La salida de hashCode es susceptible de cambiar entre las implementaciones de JVM e incluso entre las diferentes ejecuciones de un programa en la misma JVM.

Sin embargo, en el ejemplo específico que le dio, el valor de "test".hashCode()se realidad sea consistente debido a que la aplicación de hashCode para String objetos es parte de la API de String (ver the Javadocs for java.lang.String y this other SO post).

+0

(Aunque será diferente si puede encontrar un JDK 1.0. La definición errónea en los documentos de la API arrojaría excepciones si se implementa). –

+0

También está bien definido para la mayoría de las colecciones – finnw

5

De la API

El contrato general de hashCode es:

  • Cada vez que se invoca en el mismo objeto más de una vez durante una ejecución de una aplicación Java, el método hashCode siempre debe devolver el mismo número entero, siempre que no se modifique la información utilizada en comparaciones iguales en el objeto. Este entero no necesita ser consistente desde una ejecución de una aplicación hasta otra ejecución de la misma aplicación.
  • Si dos objetos son iguales de acuerdo con el método equals (Object), al llamar al método hashCode en cada uno de los dos objetos debe producir el mismo resultado entero.
  • No es necesario que si dos objetos son desiguales de acuerdo con el método igual (java.lang.Object), al llamar al método hashCode en cada uno de los dos objetos debe producir resultados enteros distintos. Sin embargo, el programador debe tener en cuenta que la producción de resultados enteros distintos para objetos desiguales puede mejorar el rendimiento de hashtables.

Tanto como sea razonablemente práctico, el método hashCode definido por la clase Object devuelve enteros distintos para objetos distintos. (Esto se implementa normalmente mediante la conversión de la dirección interna del objeto en un entero, pero esta técnica de implementación no es requerida por el lenguaje de programación Java ™.)

+0

+ 1 para citar la parte correcta de api. –

+2

-1 esto no responde la pregunta – finnw

+5

@finnw: Sí lo hace; No es necesario que hashCode devuelva el mismo valor en diferentes * ejecuciones * de la misma versión en el mismo sistema para la misma aplicación, sin importar a través de diferentes versiones o diferentes sistemas o diferentes aplicaciones. –

2

No, el resultado de hashCode() es solamente constante durante una sola ejecución . No debe esperar que el resultado de la función sea el mismo entre las ejecuciones, y mucho menos entre las versiones o las plataformas de JRE.

0

En primer lugar, el resultado de hashCode depende en gran medida del tipo de objeto y su implementación. cada clase, incluidas sus subclases, puede definir su propio comportamiento. Puede confiar en él siguiendo el contrato general tal como se describe en el javadoc y en otras respuestas. pero no es necesario que el valor permanezca igual después de reiniciar la máquina virtual. especialmente si depende de las implementaciones .hashCode de las clases de terceros.

cuando se refiere a la implementación concreta de la clase String, no debe depender del valor de retorno. si el programa se ejecuta en una VM diferente, podría cambiar potencialmente.

si se refiere únicamente a Sun Vm, podría argumentarse que Sun no romperá, ni siquiera programó mal, el código existente.por lo que "prueba" .hashCode() siempre devolverá exactamente 3556498 para cualquier versión de Sun VM.

si quieres dispararte deliberadamente en el pie, sigue adelante y depende de esto. las personas que necesiten reparar el código que se ejecuta en la "VM Nintendo Java 2015 para secador de pelo" gritarán su nombre por la noche.

0

Como se señaló, para muchas implementaciones, el comportamiento predeterminado de hashCode() es devolver la dirección del objeto. Obviamente, esto puede ser diferente cada vez que se ejecuta el programa. Esto también es consistente con el comportamiento predeterminado de equals(): dos objetos son iguales solo si son el mismo objeto (donde x y y son ambos no nulos, x.equals (y) si y solo si x == y) .

Para las clases donde hashCode() y equals() se anulan, generalmente se calculan de manera determinista en función de los valores de algunos o todos los miembros. Por lo tanto, en la práctica es probable que si un objeto en una ejecución del programa puede decirse que es igual a un objeto en otra ejecución del programa, y ​​el código fuente es el mismo (incluyendo cosas tales como el código fuente de String). .hashCode() si es invocado por hashCode() override), los códigos hash serán los mismos.

No está garantizado, aunque es difícil pensar en un ejemplo real del mundo real.

+0

@Mark: un ejemplo razonable es donde reemplaza ' hashCode() 'y el hashcode calc incluye el hashcode de un objeto componente cuyo' hashCode() 'no se anula. –

+0

Eso lo haría, pero entonces no podrías permitir que dos objetos sean iguales. Dos objetos "iguales" tendrían diferentes hashcodes. Si coloca ese objeto en un HashMap, no podrá encontrarlo nuevamente. –

0

La única verdad: hashcode es el mismo para la ejecución de la aplicación. Otra ejecución puede dar otros hashcodes.

Cuando solicita el código hash del objeto, JVM lo crea utilizando uno de los algoritmos RNG y lo coloca en el encabezado del objeto para uso futuro. Solo mire en la función get_next_hash en OpenJDK.

El algoritmo generador de números aleatorios es configurable con arg JVM -XX: hashCode = x, donde x es un dígito:

0 - Park-Miller RNG (predeterminado)

1 - f (dirección , lo global)

2 - constante 1

3 - contador secuencial

4 - la dirección del objeto en el montón

5 - Xorshift (el más rápido)

Cuando el código hash es igual a la dirección en el montón - esto es a veces difícil, porque GC puede mover objetos a otras células montón etc.

Cuestiones relacionadas