Análise de código-fonte Hashmap1.7

Estrutura de dados

HashMap Estrutura de dados adotada = matriz (principal) + lista isolada (sub)

A estrutura principal do HashMap é semelhante a uma matriz. Ao adicionar valores, o local de armazenamento é determinado pela chave. Cada local é uma estrutura de dados de entrada. Essa estrutura pode formar uma lista vinculada. Quando ocorre um conflito, os pares de valores-chave do mesmo valor de hash formam uma lista vinculada. .

Essa combinação de lista vinculada a matriz + pode ter bom desempenho na maioria dos casos.Java6 e 7. são projetados dessa maneira.No entanto, em casos extremos, ocorreu um conjunto de pares de valores-chave (como cuidadosamente projetados). Em caso de conflito, a estrutura de hash nesse momento degenerará em uma lista vinculada, causando uma queda acentuada no desempenho do HashMap.

 

 

 

método put

 / ** 
  * Associa o valor especificado à chave especificada neste mapa. 
  * Se o mapa continha anteriormente um mapeamento para a chave, o 
  valor * antigo é substituído. 
  * 
  * @Param key chave com a qual o valor especificado deve ser associado 
  * @ param valor valor a ser associado com a chave especificada 
  * @return o valor anterior associada com <tt> tecla </ tt>, ou 
  * <tt> nulo </tt> se não houver mapeamento para a <tt> chave </tt>. 
  * (Um retorno <tt> null </tt> também pode indicar que o mapa 
  * associou anteriormente <tt> null </tt> à <tt> chave </tt>.
  
 V put (chave K, valor V) {
     // Se a matriz estiver vazia, execute a inicialização. 
     if (table == EMPTY_TABLE) {
          inflateTable (threshold); 
     } 
     if (key == null )
      // Se a chave estiver vazia, mova o valor para a posição 0 da matriz e substitua o 
         retorno putForNullKey (value se houver um valor na posição 0 );
       // Calcula o valor do hash da chave 
     int hash = hash (chave);
      // Calcula o índice de posição com base no valor do hash e no comprimento da matriz que armazena os dados 
     int i = indexFor (hash, table.length);
      // Encontre se a posição correspondente possui Valor, se houver, substitua-o por um novo valor 
     para (Entrada <K, V> e = tabela [i]; e! = Nulo ; e = e.next) {
         Objeto k;
         if (e.hash == hash && ((k = e.key) == chave || key.equals (k))) { 
             V oldValue = e.value; 
             e.value = value;
              // implementação vazia do HashMap, Pode ser ignorado 
             e.recordAccess ( this );
              return oldValue; 
         } 
     } 
     // Registre os tempos de modificação mais 1 
     modCount ++ ;
      // Inclua o mapeamento do valor-chave na matriz 
     addEntry (hash, chave, valor, i);
      return  null ; 
 }

Inicializar o método de matriz inflateTable

/ ** 
  * Infla a tabela. 
  * / 
 Private  void inflateTable ( int toSize) {
      // Encontre uma potência de 2> = toSize // Encontre a menor 
     potência de 2
      maior que toSize, por exemplo, toSize = 23 e, em seguida, capacidade É 2 ^ 6 = 32 int capacidade = roundUpToPowerOf2 (toSize); // Calcule o limite de expansão de acordo com a capacidade e o fator de carga.Quando
      a capacidade atingir esse limite, o HashMap expandirá a capacidade. 
     threshold = ( int ) Math.min (capacidade * loadFactor, MAXIMUM_CAPACITY + 1 );
      // inicializa EntiEntry <K, V> [] 
     tabela de tamanho de armazenamento da matriz = nova entrada [capacidade];
      // inicializa o HashSeed 
     initHashSeedAsNeeded (capacidade); 
 }

 método de transferência

transferência de void (Entry [] newTable, rehash booleano ) {
         int newCapacity = newTable.length ;
        para (Entrada <K, V> e: tabela) {
             while ( null ! = e) { 
                Entrada <K, V> next = e.next;
                if (refazer) { 
                    e.hash = null == e.key? 0 : hash (e.key); 
                } 
                int i = indexFor (e.hash, newCapacity); 
                e.next = newTable [i]; 
                newTable [i] =e; 
                e = próximo; 
            } 
        } 
    }

 Esse código é HashMapuma operação de expansão, realocando o subscrito de cada bucket e usando a interpolação de cabeçalho para migrar os elementos para a nova matriz. O método de interpolação da cabeça reverterá a ordem da lista vinculada, que também é o ponto principal para formar um loop sem fim. Depois de entender o método de inserção da cabeça, continue olhando para baixo como causar um loop sem fim e perda de dados.

 

 

 

 

 

 

 

 

 

 

 

 

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

 

Acho que você gosta

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