Pregunta rápida: Si deseo usar HashMap
con una clase personalizada como clave, debo ¿Reemplace la función hashCode
? ¿Cómo funcionará si no anulo esa función?Uso de HashMap con la clave personalizada
Respuesta
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.
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).
Si no reemplaza hashCode AND es igual, obtendrá el comportamiento predeterminado que es que cada objeto es diferente, independientemente de su contenido.
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()
.
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
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". –
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.
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
- Si una clase anula
equals()
, debe anularhashCode()
. - Si 2 objetos son iguales, entonces sus valores
hashCode
deben ser iguales también. - Si no se usa un campo en
equals()
, entonces no se debe utilizar enhashCode()
. - Si se accede con frecuencia,
hashCode()
es un candidato para el almacenamiento en caché para mejorar el rendimiento.
- 1. Implementación de HashMap personalizada
- 2. Uso eficiente de Hashmap
- 3. Uso <c:forEach> con HashMap
- 4. Crear un hashmap con una doble clave
- 5. java HashMap iteración clave
- 6. llamando a containsKey en un hashmap con clase personalizada
- 7. Uso de la raíz personalizada con FiddlerCore
- 8. Actualización de Java HashMap clave
- 9. Uso de una matriz booleana como clave de diccionario personalizada
- 10. ArrayList como clave en Hashmap
- 11. Java HashMap Quitar clave/valor
- 12. Uso de ArrayList o HashMap
- 13. Comprobación de existencia de clave en HashMap
- 14. Uso de una aplicación personalizada con InstrumentationTestCase
- 15. Scala: Uso de HashMap con un valor predeterminado
- 16. Configuración de la clase propia como clave en Java Hashmap
- 17. Almacenamiento y recuperación del valor de la clave Java HashMap
- 18. Uso de JSTL cómo "poner" un valor en un HashMap
- 19. delphi hashmap?
- 20. ¿Cómo uso una fuente personalizada con la biblioteca Batik SVG?
- 21. Scala con el uso de palabras clave
- 22. Asignación de Hashmap a Hashmap
- 23. Eclipse con Java Advertencia HashMap
- 24. Obtener clave de un HashMap usando el valor
- 25. Java XStream con HashMap
- 26. Java: ¿obtiene el índice de clave en HashMap?
- 27. hashmap de memoria baja recomendado para la implementación de Java
- 28. cómo usar hashMap con JTable
- 29. Uso práctico de la palabra clave `stackalloc`
- 30. ¿Es posible cambiar el nombre de una clave Hashmap?
A menos que esté extendiendo algo que tenga un hashCode que funcione para él – Miquel