2012-07-01 24 views

Respuesta

3

Técnicamente, no tiene que anular el método hashCode siempre que los objetos iguales tengan el mismo hashCode.

Entonces, si usa el comportamiento predeterminado definido por Object, donde equals solo devuelve verdadero solo para la misma instancia, entonces no tiene que anular el método hashCode.

Pero si no anula los métodos equals y hashCode, significa que debe asegurarse de utilizar siempre la misma instancia de clave.

ej .:

MyKey key1_1 = new MyKey("key1"); 

myMap.put(key1_1,someValue); // OK 

someValue = myMap.get(key1_1); // returns the correct value, since the same key instance has been used; 

MyKey key1_2 = new MaKey("key1"); // different key instance 

someValue = myMap.get(key1_2); // returns null, because key1_2 has a different hashCode than key1_1 and key1_1.equals(key1_2) == false 

En la práctica a menudo tienen sólo una instancia de la clave, por lo que técnicamente no tiene que anular los métodos equals y hashCode.

Pero es mejor anular los métodos iguales y hashCode para las clases utilizadas como teclas de todos modos, porque algún tiempo después usted u otro desarrollador pueden olvidar que se debe usar la misma instancia, lo que puede ocasionar problemas difíciles de rastrear.

Y tenga en cuenta: incluso si anula los métodos equals y hashCode, debe asegurarse de no cambiar el objeto clave de una manera que cambiaría el resultado de los métodos iguales o de código hash; de lo contrario, el mapa no ganaría ' t encuentra tu valor más. Es por eso que se recomienda utilizar objetos inmutables como claves si es posible.

3

La única vez que no tiene que anular la función hashCode() es cuando también no se sobreescribe equals, por lo que utilizar el Object.equals definición por defecto de la igualdad de referencia. Esto puede ser o no lo que quiera, en particular, se considerarán iguales objetos diferentes no, incluso si tienen los mismos valores de campo.

Si reemplaza equals pero no hashCode, estarán indefinidos HashMap comportamiento (es decir: no tiene ningún sentido en absoluto, y serán completamente dañado).

4

Si no reemplaza hashCode AND es igual, obtendrá el comportamiento predeterminado que es que cada objeto es diferente, independientemente de su contenido.

+2

A menos que esté extendiendo algo que tenga un hashCode que funcione para él – Miquel

2

Depende de la clase de objeto que esté utilizando como clave. Si se trata de una clase personalizada como la que propone, y no extiende nada (es decir, se extiende a Object), la función hashCode será la de Object, y eso tendrá en cuenta las referencias de memoria, haciendo que dos objetos parezcan iguales para usted. diferentes códigos

Así que, sí, a menos que amplíe una clase con una función hashCode() que sepa que funciona para usted, debe implementar la suya propia. También asegúrese de implementar equals(): algunas clases como ArrayList solo usarán iguales, mientras que otras como HashMap comprobarán en hashCode() y equals().

+0

Tiene toda la razón. Acabo de comprobar HashMap.put() para estar seguro, y de hecho lo tuve mal. ¡Gracias! Arreglé la respuesta para reflejar tu comentario. – Miquel

+1

Sin verificar los detalles de implementación, puede ver que en un nivel abstracto debe ser así debido a la imposibilidad de colisiones hash. Dos objetos que colisionen en un código hash terminarían igual si no se considerara "igual". –

0

Considere también que si su llave no es inmutable puede tener problemas. Si coloca una entrada con una clave mutable en el mapa y luego cambia la clave de forma que afecte el código hash e iguala, puede perder su entrada en el mapa, ya que no podrá recuperarla más.

0

Debe reemplazar los métodos equals() y hashCode() de la clase Object. La implementación predeterminada de equals() y hashcode(), que se heredan de java.lang.Object utiliza la ubicación de memoria de una instancia de objeto (por ejemplo, [email protected]). Esto puede causar problemas cuando dos instancias de un objeto tienen las mismas propiedades pero el equals() heredado devolverá false porque usa el memory location, que es diferente para las dos instancias.

También se puede anular el método toString() para proporcionar una representación de cadena apropiada de su objeto.

principales consideraciones en la aplicación de un usuario definido clave

  1. Si una clase anula equals(), debe anular hashCode().
  2. Si 2 objetos son iguales, entonces sus valores hashCode deben ser iguales también.
  3. Si no se usa un campo en equals(), entonces no se debe utilizar en hashCode().
  4. Si se accede con frecuencia, hashCode() es un candidato para el almacenamiento en caché para mejorar el rendimiento.