Hash源码阅读

1.JDK 1.8中对hash算法和寻址算法如何优化

 

  • hash算法:hash = (h = key.hashCode()) ^ (h >>> 16)

 

  • 寻址算法:(n - 1) & hash ========= hash对n取模是一样的-----------------------------》定位数组的索引位置

 

  • 与运算(&),取模性能差一些(数组的长度会一直是2的n次方,只要保持数组长度是2的n次方)

 

  • hash算法没优化前的寻址核心在于低16位之间进行与运算

 

  • hash算法的优化:对每个hash值,在他的低16位中,让高低16位进行了异或(^),让他的低16位同时保持了高低16位的特征,尽量避免一些hash值后续出现冲突,大家可能会进入数组的同一个位置。

  • 寻址算法的优化:用与运算替代取模,提升性能。

 

2.HashMap如何解决hash碰撞的问题?

 

  • 当发生hash冲突时,会在这个位置挂一个链表,这个链表里面放入多个元素,让多个key-value对,同时放在数组的一个位置里。

  • 假设链表很长,可能会导致遍历链表,性能比较差,O(n)

  • 优化:如果链表的长度达到了一定的长度(8)之后,会把链表转为红黑树,遍历一遍红黑树找一个元素,O(logn)性能比链表高一些。

 

3.Hash如何进行扩容?

 

  • 进入扩容有两个情况:

    • 添加一个数据,底层数组为空时----》扩容

    • 添加一个数据之后,判断当前的数组长度是否大于threshold,大于就进行扩容

  • 2倍扩容(减少hash冲突),数组变大会进行rehash

  • 扩容过程:

    • 1、找到新的容量大小和新的threshold大小

    • 2、把旧的数据全部复制到新的数组中去

    • --

    • 将节点加到链表后

    • 容量扩充为原来的两倍,然后对每个节点重新计算哈希值

    • 这个值只可能在两个地方:一种是在原下标位置,另一种是在下标为<原下标+原容量>的位置

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值