前置知识:
& 位与操作
按位“与”操作符,如果两个数的二进制,相同位数都是1,则该位结果是1,否则是0.
比如 16 的二进制是 10000 ,15 的二进制是 1111,则在对 16和15进行按位“与”操作时,15 会发生补位操作:
10000
01111
-------
00000 ==>0
比如 10 的二进制是 1010,15 的二进制是 1111,则在对 16和15进行按位“与”操作时
1000
1111
-------
1000 ==> 10
| 位或操作
按位“或”操作符,如果两个数的二进制,相同位数有一个是1,则该位结果是1,否则是0
HashMap:
基本概念
1:数组+链表
2:加载因子 0.75,初始化容量 16
3:红黑树和列表转化条件
// 链表长度>8时链表转化成红黑树
static final int TREEIFY_THRESHOLD = 8;
// 链表长度<6 时从红黑树转化成 链表
static final int UNTREEIFY_THRESHOLD = 6;
// 单个链表长度大于64从链表转化成 红黑树
static final int MIN_TREEIFY_CAPACITY = 64;
put 操作简单分析
final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) {
HashMap.Node[] tab;
int n;
// 数组为空进行初始化。
if ((tab = this.table) == null || (n = tab.length) == 0) {
n = (tab = this.resize()).length;
}
Object p;
int i;
// 位运算 hash 与HashMap的2的次幂
// https://www.icode9.com/content-1-647683.html
// https://www.yht7.com/news/11148
if ((p = tab[i = n - 1 & hash]) == null) {
tab[i] = this.newNode(hash, key, value, (HashMap.Node)null);
} else {
Object e;
Object k;
if (((HashMap.Node)p).hash == hash && ((k = ((HashMap.Node)p).key) == key || key != null && key.equals(k))) {
e = p;
} else if (p instanceof HashMap.TreeNode) {
e = ((HashMap.TreeNode)p).putTreeVal(this, tab, hash, key, value);
} else {
int binCount = 0;
while(true) {
if ((e = ((HashMap.Node)p).next) == null) {
((HashMap.Node)p).next = this.newNode(hash, key, value, (HashMap.Node)null);
if (binCount >= 7) {
this.treeifyBin(tab, hash);
}
break;
}
if (((HashMap.Node)e).hash == hash && ((k = ((HashMap.Node)e).key) == key || key != null && key.equals(k))) {
break;
}
p = e;
++binCount;
}
}
if (e != null) {
V oldValue = ((HashMap.Node)e).value;
if (!onlyIfAbsent || oldValue == null) {
((HashMap.Node)e).value = value;
}
this.afterNodeAccess((HashMap.Node)e);
return oldValue;
}
}
++this.modCount;
if (++this.size > this.threshold) {
this.resize();
}
this.afterNodeInsertion(evict);
return null;
}
网友评论