colisión HashMap1.8hash y método de expansión

¿Por qué estudiar Hashmap fuente
debido a que trabajan en la recopilación y el proceso de aprendizaje es muy común, y el código está escrito de una manera muy elegante, si usted desea conseguir un trabajo como de salarios altos, y ahora la ciudad
superficie jdk1.8 ha hecho popular, creo que el proceso de la entrevista, el entrevistador va a pedir más y más conocimiento del código fuente, el código fuente es todo lo que tenemos que entender
, la siguiente pregunta que tenemos que aprender concebido antes de que el origen de la hashMap1.8 fuente de juntas
para el pensamiento
de inicialización 1. Hashmap tamaño es el número
2. Hashmap lo que era la estructura
3. Si usted tiene una estructura de datos que está lista Hashmap además una matriz, entonces ¿cómo vamos a colisiones hash Evita
4. Hashmap lo que la expansión tiempo
el enfoque de expansión es lo que
los papeles oficiales
Hashmap estructura
1. 1.8 en, configuración Hashmap' en matrices y matriz, además de la cadena + árbol rojo-negro, a causa de la consideración de 1,8 sin la lista de índice, la baja eficiencia de atravesar la
inferior, por lo que cuando la longitud de cadena es mayor que 8-1 es decir 0700 se convertirá en árbol rojo-negro, a continuación, cuando la longitud es de menos de 6, y se convertirá en un árbol rojo-negro en la lista
como la estructura de datos que describe la fuente es transi ent nodo <K, V> [ ] mesa; y es un solo objeto lista de nodos, la estructura es una lista de arreglo +  
 

[Java]  llanura vista de texto  Copiar el código
?
1
2
static final int TREEIFY_THRESHOLD = 8; 树的临界点
static final int UNTREEIFY_THRESHOLD = 6;非树的临界点


hash de colisión
1. Ahora que conocemos la estructura de Hashmap, luego el siguiente, vamos a ver cómo se coloca problema de colisión de hash, de acuerdo con nuestra visión, yo
puedo dejarlo a la longitud de módulo de la matriz, tales como una matriz longitud es de 16, podemos usar el valor hash del módulo clave de la matriz, para tomar los valores positivos son 0-15
buena ubicación puede caer en la matriz, sin embargo, esto no garantiza que la tan digital como sea posible la dispersión cae gama , mientras que un exceso cae en los mismos elementos de nodo
dará lugar a la formación de la longitud de la lista es demasiado larga, y que afectan el valor de hashMap velocidad, por lo que ahora vemos cómo se implementa el código fuente

[Java]  llanura vista de texto  Copiar el código
?
01
02
03
04
05
06
07
08
09
10
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
} i
f ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newNode(hash, key, value, null);
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16


Tomados en conjunto, este método de dos parámetros que intervienen en el cálculo
option1: valor hash
OPCION2: longitud de la matriz -1 de manera que la longitud de la matriz, y el comentario en la fuente se ha señalado, la longitud de las necesidades de la matriz para ser 2 ^ n-ésima potencia, es decir, el incluso
un valor int de hash, que pueden suponer un azar:
010101010101001010101010101010
con un número par o de un no-uniforme-operación y tomar lo que sería el resultado?
Si se toma un número impar y el resultado obtenido, es decir, y puede ser un número impar, puede ser un número par, y un aunque sólo la respuesta es a & número par,
por lo que la respuesta es obvia, sólo cuando la longitud de la matriz es un número par n, es decir, 2 cuando el poder en este momento para garantizar que las cifras resultantes pueden ser incluso posible que también es extraño
que nos fijamos en los primeros valores, el primer valor es un valor hash, y los valores de hash sólo puede longitud - 1 operación de la matriz, por lo que si se supone valor hash para tomar directos y
los cálculos de matriz, que corresponde al valor de hash sólo unos pocos implicados en la operación, y los otros bits que no participan en la operación, esto también puede ser diferentes elementos que dan
el mismo resultado (es decir, igual a la última pocos pero la primera unos pocos diferente), los enfoques utilizados en el código fuente es el valor hash a la derecha 16 para darle los 16 superiores
bits, y 16 bits más bajos, teniendo XOR, por lo que podemos asegurar que la totalidad de los valores hash están involucrados operación, y que la discrepancia, o por qué? Tal como exclusiva o pueden obtenido
0,1 posible binaria media
Ejemplo
0 1 0 1
0 1 0 1 y tomar
probabilidad de 00 010 0,75 1 0,25
0. 11 0
0 1 0 1 toma |
0 1 1 1 probabilidad 0 0,25 1 0,75
. 1 0 1 0
0 1 0 1 toma ^
0 1 1 0 probabilidad de una probabilidad. 1 0,5 0,5
el hash proceso de expansión
en el proceso de expansión de cambio de tamaño 1,8 Hashmap se determina por el método de
este método sirve para dos propósitos
1. Inicialización
2. Expansión

[Java]  llanura vista de texto  Copiar el código
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
dieciséis
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
{
for (int j = 0; j < oldCap; ++j) {
Node<K,V> e;
if ((e = oldTab[j]) != null) {
oldTab[j] = null;
if (e.next == null)
newTab[e.hash & (newCap - 1)] = e;
else if (e instanceof TreeNode)
((TreeNode<K,V>)e).split(this, newTab, j, oldCap);
else { // preserve order
Node<K,V> loHead = null, loTail = null;
Node<K,V> hiHead = null, hiTail = null;
Node<K,V> next;
do {
next = e.next;
if ((e.hash & oldCap) == 0) {
if (loTail == null)
loHead = e;
else
loTail.next = e;
loTail = e;
} e
lse {
if (hiTail == null)
hiHead = e;
else
hiTail.next = e;
hiTail = e;
}
} while ((e = next) != null);
if (loTail != null) {
loTail.next = null;
newTab[j] = loHead;
} i
f (hiTail != null) {
hiTail.next = null;
newTab[j + oldCap] = hiHead;
}
}
}
}
}


Este método es para decidir la expansión del código de núcleo
primero se atravesar la matriz transversal de tres párrafos de la lógica
1 si el elemento de la matriz es nulo, y si un valor nulo, entonces la cola de interpolación (1,7 se utiliza en el primer método de interpolación, pero la primera insertado en una situación de multiproceso puede
morir lista circular aparece aquí no mucho sobre interpretación)
2. Si el árbol rojo-negro se procesa a continuación en el manejo de árbol rojo-negro
3. Si los elementos de la matriz, de acuerdo con nuestras ideas, debemos la clave es re-calcular la posición en la matriz de
código del núcleo: es e.hash y oldCap
hemos encontrado que cuando se calcula, no calcular directa y oldCap -1 y en lugar de directamente calculada y la longitud de la matriz
luego de nuevo este cálculo en el aspecto forma en este sofisticado algoritmo de cómo es:
la primera vez que la expansión, el método de cambio de tamaño de la ejecución

[Java]  llanura vista de texto  Copiar el código
?
1
2
3
4
5
6
7
8
9
if (oldCap > 0) {
if (oldCap >= MAXIMUM_CAPACITY) {
threshold = Integer.MAX_VALUE;
return oldTab;
} e
lse if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&
oldCap >= DEFAULT_INITIAL_CAPACITY)
newThr = oldThr << 1; // double threshold
}


此时数组的长度已经扩大了两倍
新长度是32 ,老长度是16
0101010101010010101010101 0 1 0 1 0
0 1 1 1 1 老长度-1 //1
1 0 0 0 0 老长度 //2
0 1 1 1 1 1 新长度-1 //3
用 1,3对比,我们可以发现,数组移动不移动是看第五位是否是0 ,如果是0 ,不移动,如果不是0 ,新长度的值要
比原来的值 大16
用2,3 对比,如果第五5位是0,那么得到的结果就是0 ,如果第五位非0 ,那么得到的结果就不是0
1,3移动---> 第五位非0 ,且移动16 位 ---> 第五位 0 , 不移动
2,3 ---> 第五位非0 ,知道要移动了,且在源码中可以发现,移动了16
第五位 0 ,不移动

[Java] 纯文本查看 复制代码
?
1
2
3
4
if (hiTail != null) {
hiTail.next = null;
newTab[j + oldCap] = hiHead;
}


所以移动不移动,只需要看倒数第五位即可,不得不说,hashMap这个设计很精妙
结束语
相信通过刚才的学习,同学们已经对hash的碰撞问题和hash的扩容方法有了一个具体的认识,希望大家继续认真
学习。

发布了966 篇原创文章 · 获赞 11 · 访问量 3万+

Supongo que te gusta

Origin blog.csdn.net/xiaoyaGrace/article/details/105270495
Recomendado
Clasificación