Análisis de código fuente Hashmap1.7

Estructura de datos

HashMap Estructura de datos adoptada = matriz (principal) + lista individualmente vinculada (sub)

La estructura principal de HashMap es similar a una matriz. Al agregar valores, la ubicación de almacenamiento se determina por clave. Cada ubicación es una estructura de datos de entrada. Esta estructura puede formar una lista vinculada. Cuando ocurre un conflicto, los pares clave-valor del mismo valor hash formarán una lista vinculada. .

Esta combinación de matriz + lista vinculada puede tener un buen rendimiento en la mayoría de los casos. Java6 y 7 están diseñados de esta manera. Sin embargo, en casos extremos, se ha producido un conjunto de pares clave-valor (como un diseño cuidadoso). En caso de conflicto, la estructura hash en este momento se degenerará en una lista vinculada, lo que hará que el rendimiento de HashMap disminuya considerablemente.

 

 

 

poner método

 / ** 
  * Asocia el valor especificado con la clave especificada en este mapa. 
  * Si el mapa contenía previamente una asignación para la clave, 
  se reemplaza el antiguo * valor. 
  * 
  * @param key key con la cual se asociará el valor especificado 
  * @param value value a asociar con la clave especificada 
  * @return el valor anterior asociado con <tt> key </tt>, o 
  * <tt> null </tt> si no hubo mapeo para la tecla <tt> </tt>. 
  * (Un retorno <tt> nulo </tt> también puede indicar que el mapa 
  * anteriormente asociado <tt> nulo </tt> con <tt> clave </tt>.
  
 V put (tecla K, valor V) {
     // Si la matriz está vacía, realice la inicialización. 
     if (table == EMPTY_TABLE) {
          inflateTable (umbral); 
     } 
     if (key == null )
      // Si la clave está vacía, mueva el valor a la posición 0 de la matriz y reemplace 
         return putForNullKey (valor si hay un valor en la posición 0 );
       // Calcular el valor hash de la clave 
     int hash = hash (clave);
      // Calcular el índice de posición basado en el valor hash y la longitud de la matriz que almacena los datos 
     int i = indexFor (hash, table.length);
      // Encuentra si la posición correspondiente tiene Valor, si hay un valor, reemplácelo con un nuevo valor 
     para (Entrada <K, V> e = tabla [i]; e! = Nulo ; e = e.siguiente) {
         Objeto k; 
         if (e.hash == hash && ((k = e.key) == key || key.equals (k))) { 
             V oldValue = e.value; 
             e.value = value;
              // HashMap Implementación vacía, se puede ignorar 
             e.recordAccess ( this );
              return oldValue; 
         } 
     } 
     // Registre los tiempos de modificación más 1 
     modCount ++ ;
      // Agregue la asignación de valor-clave a la matriz 
     addEntry (hash, key, value, i);
      return  null ; 
 }

Inicializar método de matriz inflateTable

/ ** 
  * Infla la tabla. 
  * / 
 Private  void inflateTable ( int toSize) {
      // Encuentra una potencia de 2> = toSize // Encuentra la 
     potencia más pequeña de 2
      mayor que toSize, por ejemplo, toSize = 23, luego capacidad Es 2 ^ 6 = 32 int capacidad = roundUpToPowerOf2 (toSize);
      // Calcular el umbral de expansión de acuerdo con la capacidad y el factor de carga. Cuando la capacidad alcanza este umbral, HashMap ampliará la capacidad. 
     umbral = ( int ) Math.min (capacidad * loadFactor, MAXIMUM_CAPACITY + 1 );
      // inicializar EntiEntry <K, V> [] 
     tabla de tamaño de almacenamiento de matriz = nueva Entrada [capacidad];
      // inicializar HashSeed 
     initHashSeedAsNeeded (capacidad); 
 }

 método de transferencia

transferencia nula (Entry [] newTable, boolean rehash ) {
         int newCapacity = newTable.length;
        para (Entrada <K, V> e: tabla) {
             while ( null ! = e) { 
                Entrada <K, V> siguiente = e.siguiente;
                if ( 
                    rehash ) { e.hash = null == e.key? 0 : hash (e.key); 
                } 
                int i = indexFor (e.hash, newCapacity); 
                e.next = newTable [i]; 
                newTable [i] =mi; 
                e = siguiente; 
            } 
        } 
    }

 Este código es HashMapuna operación de expansión, reubicando el subíndice de cada depósito y utilizando la interpolación de encabezado para migrar los elementos a la nueva matriz. El método de interpolación de cabeza invertirá el orden de la lista vinculada, que también es el punto clave para formar un bucle sin fin. Después de comprender el método de inserción de cabezales, continúe mirando hacia abajo sobre cómo causar un bucle sin fin y pérdida de datos.

 

 

 

 

 

 

 

 

 

 

 

 

https://blog.csdn.net/carson_ho/article/details/79373026

https://cloud.tencent.com/developer/article/1489931

https://www.nowcoder.com/discuss/151172

https://www.cnblogs.com/yangyongjie/p/11015174.html

 

Supongo que te gusta

Origin www.cnblogs.com/dingpeng9055/p/12449584.html
Recomendado
Clasificación