Se alguém me deixar descrever o mecanismo de trabalho do mapa de hash, eu responderei simplesmente: "regras baseadas em hash". Essa frase é muito simples, mas antes de entender essa frase, devemos primeiro entender o que é, não é?
O que é um Beh
O hash é simplesmente uma sequência exclusiva obtida após o atributo da variável/objeto ser aplicado a um determinado algoritmo, e essa sequência é usada para determinar a singularidade da variável/objeto. Uma função de hash correta deve cumprir esse critério.
Quando a função hash é aplicada ao mesmo objeto ou um objeto igual, cada execução deve retornar o mesmo valor. Em outras palavras, dois objetos iguais devem ter o mesmo hashcode.
Nota: Todos os objetos Java herdam um método HashCode () padrão da classe Objeto. Este método retorna o endereço do objeto na memória como um número inteiro.
Uma introdução à classe de entrada
A definição de um mapa é: um objeto de uma chave de mapeamento para valor. Muito simples, certo?
Portanto, deve haver um certo mecanismo no hashmap para armazenar esses pares de valores -chave. Make Hashmap tem uma entrada de classe interna, que se parece com isso.
Classe estática Entrada <k, v> implementa mapa.entry <k, v> {Key K Final;
Obviamente, a classe de entrada tem atributos para armazenar valores -chave. A chave é marcada por final. Em seguida, tentamos entender o significado dessas variáveis.
O que o método put () realmente faz?
Antes de observar a implementação do método PUT, é necessário dar uma olhada no armazenamento da instância de entrada na matriz.
/ ** * A tabela, redimensione assilessy. /*** associa o valor especificado à tecla especificada neste mapa. valor valor a ser associado à tecla Especificar* @returnar o valor anterior associado a </tt>, ou* <tt> null </tt> se theer e /tt>.* (a <tt> null </tt> O retorno também pode indicar que o mapa* associação anteriormente <tt> null </tt> key </tt>.)*/Public v put (Key, value) {if (key == null) retornar putformullKey (valor); int hash = Have (key.hashcode ()); && (k = e.key) == key || key.equals (k)) {v OldValue = E.Value; , chave, tudo);
Vamos assistir passo a passo
Primeiro, verifique se a chave é nula.
Em seguida, o valor do hash desta chave é calculado através do método HashCode () da chave, que é usado para calcular a posição na matriz do objeto de entrada. O designer da JDK assume que algumas pessoas podem escrever métodos de hashcode () muito ruins, e haverá alguns valores de hash muito grandes ou muito pequenos. Para resolver esse problema, eles introduziram outra função de hash para aceitar o hashcode () do objeto e convertê -lo com a capacidade da matriz.
Em seguida, é o método índice (hash, tabela, comprimento), que calcula a localização precisa do armazenamento de objeto de entrada.
Em seguida, é a parte principal.
A resposta é LinkedList. Se você se lembra, a classe de entrada possui uma próxima variável, essa variável sempre aponta para a próxima variável na cadeia, que atende totalmente às características da lista vinculada.
Portanto, quando ocorre uma colisão, o objeto de entrada será armazenado na forma de uma lista vinculada. O objeto de entrada atual é usado como o próximo nó do objeto de entrada que foi armazenado.
E se salvarmos a chave existente em outro valor? Logicamente, o valor antigo será substituído. Após a detecção da posição de armazenamento do objeto de entrada, o hashmap atravessará a lista vinculada por entrada nessa posição. Se você achar que o método igual é igual, a substituição será realizada.
Dessa forma, o hashmap pode garantir a singularidade da chave.
O mecanismo de trabalho do método get
Agora, aprendemos o mecanismo de armazenamento -parado no hashmap. A próxima pergunta é: como consultar os resultados de um hashmap.
De fato, a lógica é a mesma que o put.
/*** Retorna o valor ao qual a tecla Especificar é mapeada,* ou {@code null} se este mapa não contiver mapeamento para a chave. * {@code k} para um valor {@code v} tal que {@code (key == null? k == null:* key.equals (k)}, então esse método retorna {@code v}; o Theerwise* ele retorna {@code null}. usado para* distinguir os dois casos. )); = chave ||.
O código acima parece semelhante ao método put (), exceto se (e.hash == hash && ((k = e.key) == key || key.equals (k))).
Prestar atenção