HashMap
Class Node<K,V>{
final int hash; 存储的位置
Node<k,v> next;
int key;
Int value;
}
数组+链表(红黑树)
达到阈值改变为红黑树
TREEIFY_THRESHOLD 阈值 8 (链表超过8个节点变形红黑树)
UNTREEIFY_THRESHOLD = 6; (链式结构)
Hash函数
新进入的HashCode(node) .
Key.hashcode 存的位置
初始化数组 transient Node<K,V>[] table;
初始化大小 DEFAULT_INITIAL_CAPACITY = 1 << 4; (唯一运算快 )
16位的数组
充分利用数组每一个位置(0—15)
Hash()函数
Put->putVal(hash(key)): (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16).
将高16位和低16位异或
Node<K,V>[] tab; Node<K,V> p; int n, i;
1.resize()初始化/扩容 (2倍扩容)
2.p = tab[i = (n – 1) & hash]
&运算 砍掉前面的值 ()位置)
碰撞概率降低 2^n-1全为1
什么时候进行扩大?
扩容因子 DEFAULT_LOAD_FACTOR = 0.75f; 12扩容
threshold = newThr; 12
<1>数组位置为空
<2>数组位置不为空,链表
<3>数组位置不为空,红黑树
n-1&hash hash%n(一个失效,n->n-1导致所有需要重新排序)
- 为空加 红黑树增加 3.->红黑树 或 链表增加
扩容后,节点往新节点中移动
<1>下面为空 的节点重新 hash&n-1
<2>下面为红黑树 则红黑树split
<3>下面为链表
循环遍历 链表结构 当扩容的那一位1和hash值 &出来后==?0
如果为0,保持原来位置不动.
如果不为0,加上原来的capacity 扩容到后面.
1.HashMap的原理
底层使用Hash表(数组+链表)
当链表过长将链表转成红黑树实现O(logN)时间复杂度内查找
2.HashMap中put方法
1.对key求Hash值,计算下标 (h = key.hashCode()) ^ (h >>> 16)
2.如果没碰撞了就加入链中.
如果碰撞了则链表连接到后面.
3.链表长度超过阈值(8),将链表转为红黑树
4.链表满了就使用resize
HashMap关键方法:
put->putval->resize
Remove getNode