Tengo entendido que dos objetos desiguales pueden tener el mismo código hash. ¿Cómo se manejaría esto al agregar o recuperar desde un Java de HashMap?¿Qué sucede si dos objetos diferentes tienen el mismo código hash?
Respuesta
Se agregarán al mismo cubo y se usará equals()
para distinguirlos. Cada segmento puede contener una lista de objetos con el mismo código hash.
En teoría, puede devolver el mismo número entero que un código hash para cualquier objeto de una clase determinada, pero eso significa que perderá todos los beneficios de rendimiento del mapa hash y, de hecho, almacenará objetos en una lista.
¿No se aplica un hash suplementario por defecto para un Hashmap para evitar que esto suceda y presente cierta distribución? – Ajay
Punto adicional sobre el rendimiento, en java8, cuando tenemos demasiadas claves desiguales que proporcionan el mismo código hash (índice), el número de elementos en un depósito aumenta más allá de cierto umbral (TREEIFY_THRESHOLD = 8), el contenido de ese depósito cambia de uso una lista vinculada de objetos de entrada a un árbol equilibrado. Esto teóricamente mejora el rendimiento en el peor de los casos desde O (n) hasta O (log n). –
En HashMap, las claves junto con sus valores asociativos se almacenan en un nodo de lista vinculada en el depósito y las claves se comparan esencialmente en hashmap utilizando el método equals() y no mediante hashcode.
hm.put("a","aValue"); // Suppose hashcode created for key "a" is 209
hm.put("b","bValue"); // Here hashcode created for key "b" is 209 as well.
- If
a.equals(b)
vuelvetrue
,bValue
reemplazaráaValue
y se devolverábValue
. a.equals(b)
Si vuelvefalse
, otro nodo se creará en la lista del cubo, por lo que cuando se llama aget("b")
obtendrábValue
desdea.equals(b)
esfalse
.
¿Cómo puedo recuperar el valor de a si el hashcode es el mismo? Me dará bValue, pero quiero un valor. Es eso posible ? – Sanket
En ese caso, podría usar IdentityHashMap, donde diferentes objetos con el mismo hash se consideran diferentes en función de sus identidades.
Cuando dos objetos desiguales tienen el mismo valor hash, esto provoca una colisión en la tabla hash, porque ambos objetos quieren estar en la misma ranura (a veces llamado cubo). El algoritmo hash debe resolver tales colisiones. Volviendo a los recuerdos borrosos de mi curso de algoritmos universitarios, recuerdo tres formas básicas de hacerlo:
- Busque la siguiente ranura vacía en la tabla hash y coloque el objeto allí. Pros: fácil de implementar, contras: puede llevar a la agrupación de objetos y degradar el rendimiento, la capacidad puede exceder
- Tener una función hash secundaria para usar cuando hay un conflicto: Ventajas: generalmente rápido, contras: debe escribir una segunda función hash y aún puede obtener colisiones, y la capacidad puede excederse
- Haga una lista enlazada de objetos desde la ranura en conflicto de la tabla hash. Pros/Contras: generalmente rápido para los factores de función hash y de carga decente, pero pueden degradar a la búsqueda lineal en peor de los casos
Creo que las clases de hash de Java utilizan el tercer método, pero podrían usar un enfoque de combinación. Sin embargo, la clave del buen hashing es asegurarse de que la tabla hash tenga una capacidad lo suficientemente grande y de escribir buenas funciones hash. Una tabla hash que solo tiene tantos cubos como los objetos que contiene probablemente tenga conflictos. Por lo general, desea que la tabla hash sea aproximadamente dos veces más grande que la cantidad de objetos que almacena. El HashMap de Java crecerá según sea necesario, pero puede darle una capacidad de inicio y un factor de carga si lo desea.
La función hash depende del programador. Podrías devolver 0 para todos los objetos, pero eso significará que el hash (tanto de almacenamiento como de recuperación) se convertirá en O (n) en lugar de O (1) ... o en términos simples, será dog slow.
Referencia: http://www.coderanch.com/t/540275/java/java/objects-hashcode-HashMap-retrieve-objects
HashMap está trabajando en el concepto de hash y la indexación. Internamente, HashMap almacena valores en la matriz de nodos. Cada nodo se comporta como LinkedList.
Cada nodo de lista enlazada tienen 4 valores:
int hash
K key
V value
estructura
Node<K, V> next
HashMap interna:
Al insertar el valor en HashMap, se genera el primer hashcode de la clave y, basado en algún algoritmo, calculará el índice.
Por lo tanto, nuestro valor se almacenará en un índice específico con código hash, clave, valor y dirección del siguiente elemento.
Al recuperar el valor de HashMap, primero se generará el código hash y luego se indexará (de la misma manera que en el momento de la inserción). Al obtener el valor del índice, primero se buscará el código hash, si hashcode coincidirá, solo se buscará la clave del nodo mediante el método equals. Si la clave coincidirá, solo devolverá el valor o comprobará el siguiente nodo con el mismo código hash.
- 1. ¿Qué sucede cuando dos anotaciones diferentes tienen el mismo nombre?
- 2. Vea si dos objetos tienen el mismo tipo
- 3. ¿Qué sucede si dos categorías ObjC anulan el mismo método?
- 4. ¿Por qué diferentes encabezados tienen el mismo nombre?
- 5. ¿Qué sucede si lanzo ReleaseMutex() dos veces?
- 6. ver si dos archivos tienen el mismo contenido en Python
- 7. ¿Qué sucede si dos scripts de Python desean escribir en el mismo archivo?
- 8. Compruebe si dos variables tienen valores de dos conjuntos diferentes, el modo DRY
- 9. Si dos categorías diferentes tienen el mismo método, ¿cuál será invocado por el sistema de tiempo de ejecución Objective C?
- 10. Dos clases tienen el mismo nombre de tipo XML "objectFactory"
- 11. NHibernate DuplicateMappingException cuando dos clases tienen el mismo nombre pero diferentes espacios de nombres
- 12. ¿Qué sucede si llamas al mismo repetidor dos veces en la misma colección?
- 13. En C++, ¿qué sucede si dos funciones diferentes declaran la misma variable estática?
- 14. ¿Qué usa el conjunto de funciones para verificar si dos objetos son diferentes?
- 15. Dos clases tienen el mismo nombre de tipo xml
- 16. IllegalAnnotationException: Dos clases tienen el mismo nombre de tipo XML
- 17. dos DLL diferentes con el mismo espacio de nombres
- 18. ¿Por qué C# hashSet acepta agregar dos objetos con el mismo valor de getHashCode()?
- 19. InvalidCastException para dos Objetos del mismo tipo
- 20. ¿Crees dos archivos para tener el mismo hash?
- 21. Debajo del capó, ¿los objetos de Javascript tienen tablas hash?
- 22. ¿Por qué estos dos archivos tienen el mismo valor cuando uso MemoryStream?
- 23. ¿Por qué hashCode() devuelve el mismo valor para diferentes objetos en Java?
- 24. Diferentes referencias de objetos para el mismo objeto (?)
- 25. ¿Manera pitónica de verificar si dos diccionarios tienen el mismo conjunto de claves?
- 26. ¿La forma más simple de verificar si dos enteros tienen el mismo signo?
- 27. ¿Compilar el mismo código usando diferentes JDKs dará como resultado el mismo código de bytes?
- 28. dos métodos sincronizados diferentes del mismo objeto?
- 29. ¿Cómo se puede definir qué botón se presionó si ambos tienen el mismo IBAction?
- 30. ¿Cómo puedo verificar si múltiples variables tienen el mismo valor?
BTW: Puede crear muchos valores Long con el mismo código hash fácilmente para probar esto. 'new Long (n * 0x100000001L)' todos tienen un hashCode de 0 para 'n> = 0' –