Algumas notas de estudo sobre o hashmap
1. O princípio de implementação subjacente do HashMap
No JDK1.7, o HashMap é composto por uma matriz e uma lista vinculada. Após o JDK1.8, é adicionada uma estrutura de composição de árvore vermelho-preto. Quando a lista vinculada é maior que 8 e a capacidade é maior que 64, a estrutura da lista vinculada será convertida em uma estrutura de árvore vermelho-preto. .
Os elementos na matriz são chamados de hash buckets, e cada hash bucket possui quatro campos, hash, chave, valor e próximo representando o próximo nó.
2. Otimização JDK1.8 do HashMap
(1) A árvore vermelho-preta é adicionada, porque a longa lista vinculada afetará o desempenho do HashMap e reduzirá a eficiência, e a árvore vermelho-preta tem as características de adição, exclusão e modificação rápidas, o que pode efetivamente melhorar o problema de eficiência.
(2) Otimização de loop morto, método de inserção de lista vinculada é alterado para inserção de sequência positiva de cauda
(3) Otimize a expansão, o JDK1.8 escolhe usar a operação de alta ordem e.hash & olcCap para determinar se o elemento precisa ser movido durante a expansão, em vez de recalcular o valor do hash.
Por exemplo:
key1.hash = 10 0000 1010
oldCap = 16 0001 0000
Quanto maior o resultado for 0, 0 significa que a posição do elemento não será alterada durante a expansão
key2.hash = 10 0001 0001
oldCap = 16 0001 0000
No momento, o mais alto é 1, o que significa que a posição do elemento mudou durante a expansão.A nova posição do subscrito é igual à posição do subscrito original + o comprimento da matriz original
3. Loop infinito do HashMap
O principal motivo do loop sem fim antes do JDK1.7 é que o HashMap não é seguro para threads e o método de inserção antes do JDK1.8 é a primeira inserção reversa. Supondo que o tamanho padrão de um HashMap seja 2, havia originalmente uma chave (5) e agora são criados dois threads.1 T1 adiciona a chave do elemento (3) ao HashMap, t2 adiciona a chave do elemento (7) e t1 atribui o valor à próxima. t2 obtém o direito de usar a CPU. Nesse momento, e em t1 aponta para a chave (3), depois aponta para a chave (7) e, em seguida, t2 é reinicializado, e a ordem da lista vinculada é revertida. A consulta formou uma chamada de loop por um longo tempo, resultando em um loop sem fim.