把hash表的每个单元作为链表的头节点。当发生冲突时放入到同一个hash值计算索引对应的链表。
发生冲突后寻找下一个地址
对hash值再次进行hash计算
把hash表分为基本表和溢出表,当溢出时放入到溢出表;
答:不是,存储在Node中的hash值是先对key进行hashCode()进行计算,然后再无符号右位移16,再按位异或的结果。
static final int hash(Object key) {
int h;
//hashCode和右移16进行按位异或运算
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
答:通过计算一个节点的key的hashCode()值(不是简单的进行hashCode),
(数组长度-1) & hash(hash%数组长度)计算的结果得出具体的下标,如果在索引位置只有一个节点直接返回,非一个节点继续在链表或红黑树中查找。
答:索引处链表的节点数大于8(从0开始的, 多以判断条件为 >=7), 数组的长度必须大于等于64,这个时候就会转成红黑树 要么就会数组的扩容。
答:情况一:
HashMap的Size(表中记录数)达到Hash中数组长度*loadFactor(扩容因子)时扩容。即比threshold大, 进行扩容。每次扩容为原数组长度的一倍(<< 1)
情况二:
Hash表中某个链表长度到达8,且Hash表中数组的长度小于64.
答案:最大长度为 1<<30. 即:2的30次方法。
计算操作时,发现Hash表中数组长度为2的倍数效率最高,需要一直保持长度为2的倍数。数组长度最大取值为2的31次方减一。所以里面最大的2的倍数为2的30次方。
答1:单项链表
答2:JDK1.8及之后尾插法 JDK1.7及以前采用的是头插法;
答案:只有数组里某个下标中的节点个数>8, 并且数组长度>=64, 该下标中的链表转换为红黑树
答案:红黑树的查询效率高于链表
答:元素个数为8的红黑树中,高度为:4.最多查找4次就能找到需要的的值,长度为8的链表,最多找7次。
例如长度为4就转换。红黑树高度为3,最多找3次。链表最多3次。
例如长度为7就转换。红黑树高度3,最多找3次。链表最多6次。多找3次和转换的性能消耗比较不值得。
在源码上可以看出,在理想状态下,受随机分布的 hashCode 影响,链表中的节点遵循泊松分布,而且根据统计,链表中节点数是 8 的概率已经接近千分之一,而且此时链表的性能已经很差了,所以在这种比较罕见和极端的情况下,才会把链表转变为红黑树