2011-03-26 17 views
9

Entiendo por qué es importante proporcionar el mismo código hash para dos objetos iguales (a través de equals). Pero, ¿es lo contrario también cierto, si dos objetos tienen el mismo código hash, tienen que ser iguales? ¿El contrato aún se mantiene? No puedo encontrar un ejemplo en el que esto pueda suceder, porque si todos los atributos que están tomando parte en el método igual se usan para anular también el método de código hash, siempre tendremos el mismo código hash de objetos que son iguales. Por favor comenta.¿No son necesariamente iguales dos objetos Java con los mismos códigos hash?

+1

Ver http://stackoverflow.com/questions/ 4360035/why-hashcode-can-return-the-same-value-for-different-objects-in-java – esaj

Respuesta

27

Si dos objetos tienen el mismo código hash entonces NO son necesariamente iguales. De lo contrario, habrás descubierto la función hash perfecta. Pero lo contrario es cierto: si los objetos son iguales, entonces deben tener el mismo código hash.

+5

+1 esto también es relevante para los objetos hash en general, no solo para el objeto java. – MByD

+0

Considere este [ejemplo] (http://docs.oracle.com/javase/tutorial/java/IandI/objectclass.html) Aquí 'firstBook' y' secondBook' tienen diferentes hashcodes. Así que, ¿cómo se cumple su declaración? los objetos son iguales y tienen el mismo hashcode' – Fresher

+1

¡qué tonta respuesta ... él no parecía responder por qué? – anshulkatta

4

Según el Javadoc en: http://download.oracle.com/javase/6/docs/api/java/lang/Object.html#hashCode%28%29

No es necesario que si dos objetos son desiguales según las método equals (java.lang.Object), después de llamar al método hashCode en cada uno de los dos los objetos deben 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.

Editar: En el mundo real, dos cadenas pueden tener el mismo código hash. Por ejemplo, si desea almacenar todas las combinaciones de cadenas que contengan letras en minúsculas en inglés (como "aaaaaaaaaa", "aaaaaaaaab", etc.) de longitud 10, no puede asignar un código hash exclusivo a cada una de las 141.167.095.653. 376 combinaciones, ya que int en Java es de 32 bits y, por lo tanto, puede tener hasta 4.294.967.296 valores distintos.

2

Como cuestión de hecho

public int hashCode(){ 
    return 1; 
} 

es una implementación de código hash válido ... pero uno terrible. Hará que todos tus hashtables sean lentos. Pero sí, puede tener dos objetos diferentes con el mismo código hash. Pero ese no debería ser el caso general, una implementación real debería dar diferentes códigos hash para diferentes valores la mayor parte del tiempo.

+0

Este es un argumento válido. La única propiedad que debe cumplir un código hash para garantizar la corrección es que los códigos hash deben ser diferentes * solo * si las estructuras de datos subyacentes son diferentes. Esto se debe a que los diferentes códigos hash, por diseño, implican estructuras subyacentes diferentes. – Jasim

+0

¿Qué quiere decir con "diferentes estructuras subyacentes"? – NoName

2

Curiosamente, NumberFormat es un ejemplo de una clase Java Foundation que viola la recomendación de que:

tanto como sea razonablemente práctico, el método hashCode definido por clase Object Función RETURN números enteros distintos de objetos distintos.

Aquí hay un código que muestra esto, al menos bajo la versión de Java que actualmente estoy ejecutando bajo Mac OS X 10.6.

Numberformat nf = NumberFormat.getNumberInstance(); 
NumberFormat nf2 = NumberFormat.getNumberInstance(); 
assert nf != nf2; // passes -- they are different objects 
assert !nf.equals(nf2); // passes -- they are not equal 
assert nf.hashCode() != nf2.hashCode(); // fails -- same hash code 
1

hashCode valor depende de la implementación. por ejemplo, la clase String implementa la función hashCode() dependiendo del valor. significa

String a=new String("b"); 
String b=new String("b"); 

tendrá hashcode misma, pero, se trata de dos objetos diferentes. y a==b devolverá false.

4

El propósito de la función hashCode es permitir que los objetos se particionen rápidamente en conjuntos de elementos que se sabe que son desiguales para todos los elementos fuera de su propio conjunto. Supongamos que uno tiene 1,000 elementos y uno los divide en diez conjuntos de igual tamaño.Una llamada a hashCode podría identificar rápidamente el artículo como no igual a 900 de los artículos, sin tener que usar equals en ninguno de esos artículos. Incluso si uno tuviese que usar equals para comparar el artículo con otros 100 artículos, eso sería solo 1/10 del costo de compararlo con los 1000 artículos. En la práctica, incluso en una gran colección, hashCode eliminará a menudo 99.9% o más de los artículos desiguales, dejando como mucho un puñado para ser examinado.

0

El método del código hash devuelve entero. Si el rango de enteros termina, también dos objetos diferentes tendrán el mismo código hash. Por lo tanto, no es necesario que dos objetos diferentes tengan el mismo código hash son iguales.

0

Para probar, si dos objetos tienen el mismo código hash no significa que sean iguales

Digamos que tiene dos clases definidas por el usuario

class Object1{ 
     private final int hashCode = 21; 
     public int hashCode(){ 
      return hashCode; 
     } 

     public boolean equals(Object obj) { 
      return (this == obj); 
     } 
    } 

    class Object2{ 
     private final int hashCode = 21; 
     public int hashCode(){ 
      return hashCode; 
     } 

     public boolean equals(Object obj) { 
      return (this == obj); 
     } 
    } 

    Object1 object1 = new Object1(); 
    Object2 object2 = new Object2(); 

    Object1 object3 = new Object1(); 


    if(object1.hashCode() == object2.hashCode()){ 
     // return true, because the hashcodes are same 
    } 

    but 
    if(object1.equals(object3)){ 
      // will fail, because two different objects 
    } 
Cuestiones relacionadas