recorrer instead example elementos definicion adicionar java hash hashmap stack-overflow

instead - mapping en java



Bucle infinito cuando se usa una tecla varias veces en HashMap (5)

HashMap cae en un ciclo infinito.

No puedo entender por qué HashMap arroja un error de stackoverflow cuando se usa la misma clave varias veces.

Código:

import java.util.HashMap; public class Test { public static void main(String[] args) { HashMap hm = new HashMap(); hm.put(hm, "1"); hm.put(hm, "2"); } }

Error:

Excepción en el hilo "principal" java.lang.StackOverflowError


El problema no es que el mapa hash haga explotar la pila para la "misma clave" ingresada dos veces, sino debido a su elección particular de la clave del mapa. Está agregando el mapa hash a sí mismo.

Para explicar mejor, parte del contrato de Map es que las claves no deben cambiar de forma que afecte a sus métodos equals (o hashCode para ese caso).

Cuando agregaste un mapa a sí mismo como una clave, cambiaste la clave (mapa) de una manera que hace que devuelva un hashCode diferente de cuando primero agregaste el mapa.

Para obtener más información, esto es de la base JDK para la interfaz de Mapa:

Nota: se debe tener mucho cuidado si los objetos mutables se utilizan como claves de mapa. El comportamiento de un mapa no se especifica si el valor de un objeto se cambia de una manera que afecta a las comparaciones iguales mientras el objeto es una clave en el mapa. Un caso especial de esta prohibición es que no está permitido que un mapa se contenga como una clave. Si bien es permisible que un mapa se contenga a sí mismo como un valor, se recomienda extrema precaución: los métodos equal y hashCode ya no están bien definidos en dicho mapa.


Para ubicar una clave en el HashMap (que se realiza cada vez que llamas a put o get o containsKey ), se hashCode método hashCode para la clave.

Para HashMap , hashCode() es una función de hashCode() de todas las entradas del Map , y hashCode cada entrada es una función de hashCode s de la clave y el valor. Como su clave es la misma instancia de HashMap , al calcular el hashCode de esa clave se produce una recursión infinita de las hashCode método hashCode , lo que lleva a Error .

Usar una HashMap como clave para HashMap es una mala idea.


Utiliza como clave el hashmap en sí mismo -> eso significa recursión -> sin condición de salida -> .

Simplemente use una tecla (Long, String, Object, cualquier otra cosa que desee).

Y sí, como sugiere Seek Addo, agregue tipos con <> corchetes.


No es posible agregarlo a un Map como una clave. De javadoc :

Un caso especial de esta prohibición es que no está permitido que un mapa se contenga como una clave .

El problema es que está utilizando como clave no un objeto estándar (cualquier objeto con métodos equals y hashCode bien definidos, que no es el mapa en sí), sino el mapa en sí.

El problema está en cómo se hashCode el hashCode de HashMap :

public int hashCode() { int h = 0; Iterator<Entry<K,V>> i = entrySet().iterator(); while (i.hasNext()) h += i.next().hashCode(); return h; }

Como puede ver, para calcular el hashCode del mapa, itera sobre todos los elementos del mapa. Y para cada elemento, calcula el hashCode. Como el único elemento del mapa tiene como clave el mapa en sí, se convierte en una fuente de recursión.

Reemplazar el mapa con otro objeto que pueda usarse como clave (con equals bien definidos y hashCode ) funcionará:

import java.util.HashMap; public class Test { public static void main(String[] args) { HashMap hm = new HashMap(); String key = "k1"; hm.put(key, "1"); hm.put(key, "2"); } }


Está utilizando el mismo nombre de objeto como clave para que sea un bucle infinito.

entonces es un desbordamiento de pila