1 final Node<K, V> resize(){
2
3 // 用于存储重新散列后的数组
4 Node<K, V>[] newTab;
5
6 // 如果原来的数组是空的,则resize执行的是初始化操作,而不是扩容操作
7 if(table == null){
8 // 初始容量为16
9 int cap = DEFAULT_CAPACITY;// 1<<<4
10
11 // 初始的加载因子为0.75,即容量使用到3/4时就要再次扩容
12 loadFactor = DEFAULT_LOADFACTOR;
13
14 // 设置扩容阈值
15 threshold = (int)(cap * loadFactor);
16
17 newTab = (Node<K, V>[])(new Node[cap]);
18 return newTab;
19 }
20
21 // ... 省略了细节处理,例如容量到达最大值时应该怎么办,本程序段主要讲述扩容流程
22
23 // 如果原来的数组不为空,则先扩容,再把原来的数据重新散列到新的扩容后的数组中
24 int oldCap = table.length;
25 int newCap = oldCap << 1;
26 threshold = newCap * loadFactor;
27 newTab = (Node<K, V>[])(new Node[newCap]);
28
29 // 循环遍历原来的数组,进行重新散列
30 for(int i = 0; i < table.length; i++){
31
32 if(table[i] == null){
33 continue;
34 }
35
36 Node<K,V> e = table[i];
37 table[i] = null;
38
39 // 数组中每个元素下都是一个链表
40 // 如果链表只有一个元素,那么直接将其放到新位置
41 if(e.next == null){
42 newTab[e.hash & (newCap-1)] = e;
43 continue;
44 }
45
46 // 如果链表中有多个元素,则需要将其分成两个链表
47 // 为什么是两个链表呢?因为当 hash&(oldCap-1) == i 时,
48 // hash&(newCap-1) 只会有两个取值:i 和 i+oldCap
49 // 证明:
50 // 假设 oldCap = 16 = 0b10000
51 // 则 newCap = 16 <<< 1 = 0b100000
52 // 则 oldCap - 1 = 0b1111
53 // newCap - 1 = 0b11111
54 // 则 hash&(oldCap-1) 与 hash&(newCap-1) 只有 从又向左数第五位不同
55 // 又因为 0b10000 = oldCap
56 // 所以 hash&(newCap-1) == hash&(oldCap-1) == i
57 // 或 hash&(newCap-1) == hash&(oldCap-1)+oldCap == i+oldCap
58
59 // 链表1:放在原处,即 hash&(newCap-1) = hash&(oldCap-1) = i
60 Node<K, V> hiHead, hiTail;
61 // 链表2:放在 i+oldCap处,即hash&(newCap-1) = hash&(oldCap-1)+oldCap = i+oldCap
62 Node<K, V> loHead, loTail;
63 do{
64 // 将原来链表中的元素分类放到链表1、2中
65
66 // 如果散列值与原来一样(i)
67 if((e.hash & (oldCap-1)) == (e.hash & (newCap-1))){
68 if(loHead == null){
69 loHead = e;
70 } else {
71 loTail.next = e;
72 }
73 loTail = e;
74 } else {
75 // 如果散列值与原来不一样(i+oldCap)
76 if(hiHead == null){
77 hiHead = e;
78 } else {
79 hiTail.next = e;
80 }
81 hiTail = e;
82 }
83 e = e.next;
84 } while(e != null);
85
86 if(hiHead != null){
87 hiTail.next = null;
88
89 // 放在新位置
90 newTab[i+oldCap] = hiHead;
91 }
92 if(loHead != null){
93 loTail.next = null;
94
95 // 放在原处
96 newTab[i] = loHead;
97 }
98 }
99
100 return newTab;
101 }
来源:https://www.cnblogs.com/cbhe/p/12623296.html