Si alguien me deja describir el mecanismo de trabajo del mapa hash, responderé simplemente: "Reglas basadas en hash". Esta oración es muy simple, pero antes de comprender esta oración, primero debemos entender qué es lo que es, ¿no?
Que es un beh
Hash es simplemente una cadena única obtenida después del atributo de la variable/objeto se aplica a un determinado algoritmo, y esta cadena se usa para determinar la singularidad de la variable/objeto. Una función hash correcta debe cumplir con este criterio.
Cuando la función hash se aplica al mismo objeto o un objeto igual, cada ejecución debe devolver el mismo valor. En otras palabras, dos objetos iguales deberían tener el mismo hashcode.
Nota: Todos los objetos Java heredan un método hashcode () predeterminado de la clase de objeto. Este método devuelve la dirección del objeto en la memoria como un entero.
Una introducción a la clase de entrada
La definición de un mapa es: un objeto de una clave de mapeo a valor. Muy simple, ¿verdad?
Por lo tanto, debe haber un cierto mecanismo en HashMap para almacenar estos pares de valores clave. Hacer que hashmap tiene una entrada de clase interna, que se ve así.
Entrada de clase estática <K, V> Implementa MAP.Entry <K, V> {Key final K;
Por supuesto, la clase de entrada tiene atributos para almacenar valores clave. La clave está marcada por final. A continuación, tratamos de entender el significado de estas variables.
¿Qué hace realmente el método PUT ()?
Antes de observar la implementación del método PUT, es necesario echar un vistazo al almacenamiento de la instancia de entrada en la matriz.
/ ** * La tabla, cambiar el tamaño de la longitud. /*** Asocia el valor especificado con la tecla especificada en este mapa.* Si el mapa que contiene previamente para la clave, el valor anterior* es CED. Valor Valor para estar asociado con la clave especificada* @return El valor anterior asociado con </tt>, o* <tt> null </tt> if theer e /tt>.* (a <tt> null </tt> El retorno también puede indicar que el mapa* anteriormente asociación <tt> null </tt> key </tt>.)*/Public v put (k key, valor) {if (key == null) return putfornullkey (valor); int hash = have (key.hashcode ()); && (k = e.key) == Key || Key.Equals (k)) {V OldValue = E.Value; , clave, todos);
Vamos a ver paso a paso
En primer lugar, verifique si la clave es nula.
A continuación, el valor de hash de esta clave se calcula a través del método clave hashcode (), que se utiliza para calcular la posición en la matriz del objeto de entrada. El diseñador de JDK asume que algunas personas pueden escribir métodos hashcode () muy pobres, y habrá algunos valores hash muy grandes o muy pequeños. Para resolver este problema, introdujeron otra función hash para aceptar el hashcode () del objeto y convertirlo a la capacidad de la matriz.
El siguiente es el método índice (hash, tabla, longitud), que calcula la ubicación precisa del almacenamiento del objeto de entrada.
Luego es la parte principal.
La respuesta es LinkedList. Si recuerda, la clase de entrada tiene una siguiente variable, esta variable siempre apunta a la siguiente variable en la cadena, que cumple completamente con las características de la lista vinculada.
Por lo tanto, cuando se produce una colisión, el objeto de entrada se almacenará en forma de una lista vinculada. El objeto de entrada actual se usa como el siguiente nodo del objeto de entrada que se ha almacenado.
¿Qué pasa si guardamos la clave existente en otro valor? Lógicamente, el valor anterior será reemplazado. Después de detectar la posición de almacenamiento del objeto de entrada, HashMap atravesará la lista vinculada de entrada en esa posición a cada llamada de entrada, todos los objetos en esta lista vinculada tienen el mismo hastcode () y el método igual. Si encuentra que el método igual es igual, se realiza el reemplazo.
De esta manera, hashmap puede garantizar la singularidad de la clave.
El mecanismo de trabajo del método get
Ahora hemos aprendido el mecanismo de almacenamiento, empapado en Hashmap. La siguiente pregunta es: cómo consultar los resultados de un hashmap.
De hecho, la lógica es la misma que la PUT.
/*** Devuelve el valor al que se asigna la tecla especificar,* o {@code null} Si este mapa no contiene mapeo para la clave. * {@code k} a un valor {@code v} tal que {@code (key == null? k == null:* key.equals (k)}, entonces este método devuelve {@code v}; o Theerwise* Devuelve {@code null}. utilizado para* distinguir los dos casos. )); = clave ||
El código anterior se ve similar al método put (), excepto si (e.hash == hash && ((k = e.key) == key || key.equals (k))).
Prestar atención