public class HashMap<K, V> extends AbstractMap<K, V> implements Map<K, V>, Cloneable, Serializable {
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; //默认的初始容量-必须是2的幂。
static final int MAXIMUM_CAPACITY = 1 << 30; //最大容量,如果较高的值是由任何带有参数的构造函数隐式指定的。必须是2的幂<= 1<<30。
static final float DEFAULT_LOAD_FACTOR = 0.75f; //在构造函数中未指定时使用的负载因子。
static final int TREEIFY_THRESHOLD = 8; //树的临界值
static final int UNTREEIFY_THRESHOLD = 6; //在调整大小操作期间取消(分割)存储库的存储计数阈值。应小于TREEIFY_THRESHOLD,并最多6个网格与收缩检测下去除。
static final int MIN_TREEIFY_CAPACITY = 64; //最小的表容量,可为容器进行树状排列。
transient Node<K, V>[] table; //表,在第一次使用时初始化,并根据需要调整大小。分配时,长度总是2的幂。
transient Set<Map.Entry<K, V>> entrySet; //保存缓存
transient int size; //这个映射中包含的键值映射的数量。
transient int modCount; //修改的次数
int threshold; //调整大小的下一个大小值(容量*负载因子)。
final float loadFactor; //哈希表的负载因子。
//在第一次请求该视图时,每个字段都被初始化为包含适当视图的实例。视图是无状态的,因此没有理由创建多个视图。
transient volatile Set<K> keySet; (AbstractMap)
transient volatile Collection<V> values; (AbstractMap)
//基本哈希bin节点,用于大多数条目。(参见下面的TreeNode子类,以及LinkedHashMap中的条目子类)
static class Node<K, V> implements Map.Entry<K, V> {
final int hash; //哈希值
final K key; //键
V value; //值
Node<K, V> next;//下一个值
}
static final int hash(Object key){ //key的hashcode ^ hashCode >>> 16
int h;
return (key==null) ? 0 :(h = key.hashCode()) ^ (h >>> 16);
}
static final int tableSizeFor(int cap){ //该方法保证了容量的长度是2的n次幂
int n = cap - 1;
n |= n>>>1;
n |= n>>>2;
n |= n>>>4;
n |= n>>>8;
n |= n>>>16;
return (n<0) ? 1 : (n>=MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n+1;
}
final Node<K, V>[] resize() {
Node<K, V>[] oldTab = table;
int oldCap = (oldTab == null) ? 0 : oldTab.length;
int oldThr = threshold;
int newCap, newThr = 0; //新容量 与 新扩容阈值
if (oldCap > 0) { //如果容量大于0(这时候table不为null了, oldCap为16的n次幂)
if (oldCap >= MAXIMUM_CAPACITY) { //如果容量大于最大值(1 << 30)
threshold = Integer.MAX_VALUE; //取最大值
return oldTab;
} else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY && oldCap >= DEFAULT_INITIAL_CAPACITY) { //扩容(原容量*2) 并且大于等于默认容量16
newThr = oldThr << 1; // 扩容阈值(原阈值*2) 12的n次幂
}
} else if (oldThr > 0) { // 初始容量设为阈值
newCap = oldThr;
} else { // 零初始阈值表示使用默认值(第一次 put() 的时候 默认容量为16 扩容阈值为12)
newCap = DEFAULT_INITIAL_CAPACITY; // 16
newThr = (int) (DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY); // 16 * 0.75f = 12
}
if (newThr == 0) { //如果阈值为0 设置阈值(新的容量*扩展因子0.75f)
float ft = (float) newCap * loadFactor;
newThr = (newCap < MAXIMUM_CAPACITY && ft < (float) MAXIMUM_CAPACITY ? (int) ft : Integer.MAX_VALUE);
}
threshold = newThr; //扩容阈值 = 新的扩容阈值
Node<K, V>[] newTab = (Node<K, V>[]) new Node[newCap]; //实例化新的表
table = newTab; //赋值给当前table
if (oldTab != null) { //第一次put除外 就不为空
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;
} else {
if (hiTail == null)
hiHead = e;
else
hiTail.next = e;
hiTail = e;
}
} while ((e = next) != null);
if (loTail != null) {
loTail.next = null;
newTab[j] = loHead;
}
if (hiTail != null) {
hiTail.next = null;
newTab[j + oldCap] = hiHead;
}
}
}
}
}
return newTab;
}
}
Java HashMap 解析
猜你喜欢
转载自blog.csdn.net/baidu_36327010/article/details/88192831
今日推荐
周排行