2011-03-04 28 views
5

La Guía de estudio SCJP 6 de Bert Bates y Kathy Sierra indica en la página 554 (entre otros requisitos) que x.hashCode()! = Y.hashCode() requiere que x .equals (y) == falso.contrato equals() y hashCode() en Java

Pero el Javadoc para Object no menciona explícitamente dicho requisito. Cita:
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.

Debo tomar lo que dice Javadoc como una implicación material, como eq -> hc? Entonces no habría conflicto entre estas dos fuentes.

Respuesta

13

Como dice z5h, las afirmaciones son equivalentes.

Para las condiciones lógicas x y y, "x implica y" es lo mismo que "! Y assume! X".

"Si algo es un autobús, es rojo" es lógicamente equivalente a "si algo no es rojo, no es un autobús".

Esto es contraposition.

Debo tomar lo que dice Javadoc como una implicación material, como eq -> hc.

Sí, eso es exactamente lo que está diciendo: dos objetos iguales bajo equals implica que sus códigos hash deben ser iguales.

+0

¡Gracias por la aclaración! – prasopes

+8

"Si algo es un bus, es rojo" ¿Qué tan británico es usted :-) –

+0

Jon, ¿me puede dar algún ejemplo donde HashCode podría ser el mismo pero los objetos no son iguales? – UnKnown

12

Las dos declaraciones son equivalentes.

En pocas palabras:

  1. si dos hashcodes difieren, los objetos son definitivamente diferente bajo es igual.
  2. si dos hashcodes son iguales, no lo sabemos. (pero en muchos casos prácticos los objetos serán iguales).
5

No hay conflicto entre estas declaraciones, son equivalentes.

p: x.equals(y) 
q: x.hashCode() == y.hashCode() 
p implies q 
not q implies not p 
2

ABC de HashMap.
1. HashMap generará hashcode para cada clave, independientemente del tipo de objeto.
2. Para ser específico - código hash se genera en base a la clave y el valor (es decir, de entrada.)

Experimento: Considérese un objeto definido por el usuario (por ejemplo SPObject.) Es la clave para un HashMap; SPObject solo tiene un parámetro (name) en él. Consulte: http://www.programcreek.com/2011/07/java-equals-and-hashcode-contract/

Si hashCode() y equals() no se escriben correctamente en la clase SPObject, los problemas se detallan a continuación.
Poner 2 entradas - nuevo SPObject ("SP") & nuevo SPObject ("SP"). Estos se tratan como un objeto diferente y se almacenan en el mapa con éxito.

map.get (nuevo SPObject ("SP")) devolverá nulo.
map.contains (nuevo SPObject ("SP")) devolverá falso.

Este es el resultado, si el contrato hashCode/equals no se maneja correctamente.

hashCode()  | equals() | Treated as | Description
No    |  No  | Duplicate | Stored in different buckets. 
              | Treated as different object. 

Yes   |  No  | Duplicate | Stored in same bucket. 
              | Treated as different object. 
              | Because, the default(Object) equals method will check only the reference of objects.  

No    |  Yes  | Duplicate | Stored in different buckets.Treated as different object 

Yes(hashlogic) |  Yes  | Unique  | Stored in same bucket.Treated as same object.Efficient. 

Yes(constant) |  Yes  | Unique  | Stored in same bucket.Treated as same object. 
              | Inefficient, because it will iterate bucket elements for equality check. 

+0

muy bien explicado !! – anandaravindan

0

La idea fundamental detrás de hashCode es que una entidad que sabe que un objeto ha reportado un valor hashCode diferente de lo que algún otro objeto tiene derecho a suponer que los objetos no son iguales sin tener que examinarlos cualquier promover. Debido a que los enteros mantienen varios axiomas relacionados con la equivalencia, una entidad puede saber que dos códigos hash difieren sin compararlos directamente. Por ejemplo, saber que uno de ellos ha informado un número par y el otro un número impar sería suficiente para demostrar que no pueden coincidir. Tales suposiciones a menudo permiten a las entidades identificar rápidamente grandes porciones de colecciones que posiblemente no pueden contener un objeto que se busca, y por lo tanto no se molestan en examinar esas áreas.

Los dos "requisitos" citados sobre hashCode e iguales incluyen una premisa no declarada: en los casos en que X.equals(Y) informa verdadero, uno no querrá que las entidades asuman erróneamente que es falso. En general, es muy malo para el código actuar sobre suposiciones falsas, por lo que la premisa de que uno no querría que las entidades hicieran suposiciones incorrectas sobre la igualdad de los objetos es razonable. La cita de la Guía de estudio alude al hecho de que si dos objetos tienen códigos hash desiguales, se presumirá que son desiguales; hacer que tal presunción coincida con la realidad requiere que ellos sean desiguales. El JavaDoc esencialmente alude al hecho de que si dos objetos son iguales, y uno quiere evitar que las entidades asuman que no lo estarán y no se dan cuenta de que sí lo están, uno debe asegurarse de que un valor hashCode devuelto por uno también sea devuelto por el otro.

Cuestiones relacionadas