JAVASE_HashMap底层源码分析(常见面试题)

1.存储在Node中的hash值,是否就是key的hashCode()?

        答案: 不是。存储的是对key先做hashCode()计算,计算出来的值然后在无符号向右位移16位,最后这两个值做异或运算。

2.如何知道一个节点到底存储在Hash表(散列表)的哪个位置?

        答案:先对key做相关的Hash值(不是简单地HashCode值),然后再和(数组长度-1)做按位与运算,计算所得就是具体的下标。如果下标只有这一个节点,直接存入返回;如果还有其它节点,继续在链表和红黑树中查找;

if ((p = tab[i = (n - 1) & hash]) == null)
    //将节点放入数组中
    tab[i] = newNode(hash, key, value, null);

//i = (n - 1) & hash  ->i就是计算出的下标的位置

3.什么时候需要把链表转为红黑树?

         答案:链表节点数大于8(从0开始的,多以判断条件为 >=7),数组长度必须大于64,要么数组进行扩容大于64后,链表转为红黑树。

4.什么时候数组会进行扩容?

        答案:情况一:HashMap中的Size达到Hash中数组长度*loadFactor(扩容因子)时扩容。也就是,Size比threshold大,进行扩容。每次扩容长度都是原数组长度中的一倍 ( <<1 )。

                情况二:Hash表中某个链表的长度达到8, 且Hash表中数组的长度小于64

/*底层源码展示*/ 

//数组扩容为之前数组长度的2倍
    else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&
             oldCap >= DEFAULT_INITIAL_CAPACITY)
      //扩容阈值变为之前的2倍
      newThr = oldThr << 1; // double threshold
  }

5.Hash表中数组最大长度为多少?

        答案: 最大长度为 1<<30 , 即 2的30次方。计算操作时,发现Hash表中数组长度为2的倍数效率最高,需要一直保持长度为2的倍数。数组长度最大取值为2的31次方减一。所以里面最大的2的倍数为2的30次方。

//最大容量
  static final int MAXIMUM_CAPACITY = 1 << 30;

6. ①Hash表中使用的是单向链表还是双向链表?

        答案: 单向链表

    ②数组扩容时,链表使用的是尾加法还是头加法?

        答案: 尾加

7.链表转为红黑树时,数组中是所有的链表转为红黑树还是什么情况?

        答案: 只有数组中某个下标中的链表节点个数 >8 ,并且 数组长度> 64 时,该下标中的链表转为红黑树。

8.为什么java8中的长度超过8以后链表就会转换为红黑树?

        答案:红黑树的查找效率高于链表

9.为什么选择8作为链表与红黑树的转换值?

        答案:当节点个数为8时,红黑树的高度为4,最多查找4次就能查到需要的值;长度为8的链表最多需要查找7次才能查到。

                例如:长度为4就转换。红黑树高度为3,最多找3次。链表最多找3次。没有差别。

                例如:长度为7就转换。红黑树高度为3,最多查找3次。链表最多6次。绝对多找3次和转换的性能消耗比较不值得。

10.总结HashMap底层原理(常见面试题)

        答案:①从java8开始HashMap底层由数组+链表 升级为 数组+链表+红黑树.

                ②使用HashMap时,当使用无参构造方法实例化时,设置扩容因子为默认扩容因子0.75。

                ③当向HashMap添加内容时, 会对key进行hash计算, 再将计算出的hash值与(数组长度-1) 进行按位与运算, 计算出存储的位置。

                ④如果计算出的存储位置没有内容,就直接存入数组中;如果该下标有其他节点,就把内容存入到链表或红黑树中。

                ⑤如果添加内容后,数组长度大于8,会判断数组长度是否大于64,如果小于64就会对数组长度进行扩容,扩容长度为原数组的一倍,扩容后把hash表中的内容重新存入到新的hash表中。如果Hash长度大于等于64,链表就会转换为红黑树。

                ⑥最终判断HashMap中元素个数是否已经达到扩容值(threshold), 如果达到扩容值,需要进行扩容,扩容长度为原扩容值的一倍。

                ⑦反之,如果删除元素后,红黑树的元素个数小于6,红黑树就会转换为链表。

                

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值