HashMap中哈希算法的关键代码

//重新计算哈希值
static final int hash(Object key) {int h;return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);//key如果是null 新hashcode是0 否则 计算新的hashcode
}//计算数组槽位(n - 1) & hash

HashMap的细节我们不谈,只看这个哈希算法的细节(h = key.hashCode()) ^ (h >>> 16)

^按位异或运算,只要位不同结果为1,不然结果为0

>>> 无符号右移:右边补0

为什么要无符号右移16位后做异或运算

根据上面的说明我们做一个简单演练

将h无符号右移16为相当于将高区16位移动到了低区的16位,再与原hashcode做异或运算,可以将高低位二进制特征混合起来

从上文可知高区的16位与原hashcode相比没有发生变化,低区的16位发生了变化

我们可知通过上面(h = key.hashCode()) ^ (h >>> 16)进行运算可以把高区与低区的二进制特征混合到低区,那么为什么要这么做呢?

我们都知道重新计算出的新哈希值在后面将会参与hashmap中数组槽位的计算,计算公式:(n - 1) & hash,假如这时数组槽位有16个,则槽位计算如下:

仔细观察上文不难发现,高区的16位很有可能会被数组槽位数的二进制码锁屏蔽,如果我们不做刚才移位异或运算,那么在计算槽位时将丢失高区特征

也许你可能会说,即使丢失了高区特征不同hashcode也可以计算出不同的槽位来,但是细想当两个哈希码很接近时,那么这高区的一点点差异就可能导致一次哈希碰撞,所以这也是将性能做到极致的一种体现

使用异或运算的原因

异或运算能更好的保留各部分的特征,如果采用&运算计算出来的值会向1靠拢,采用|运算计算出来的值会向0靠拢

为什么槽位数必须使用2^n

1、为了让哈希后的结果更加均匀

这个原因我们继续用上面的例子来说明

假如槽位数不是16,而是17,则槽位计算公式变成:(17 - 1) & hash

从上文可以看出,计算结果将会大大趋同,hashcode参加&运算后被更多位的0屏蔽,计算结果只剩下两种0和16,这对于hashmap来说是一种灾难

2、可以通过位运算e.hash & (newCap - 1)来计算,a % (2^n) 等价于 a & (2^n - 1) ,位运算的运算效率高于算术运算,原因是算术运算还是会被转化为位运算

总结

说了这么多点,上面提到的所有问题,最终目的还是为了让哈希后的结果更均匀的分部,减少哈希碰撞,提升hashmap的运行效率

HashMap中的hash算法的几个思考相关推荐

  1. HashMap中的hash函数

    在写一个HashSet时候有个需求,是判断HashSet中是否已经存在对象,存在则取出,不存在则add添加.HashSet也是通过HashMap实现,只用了HashMap的key,value都存储一个 ...

  2. HashMap中的hash与rehash

    HashMap中的hash与rehash 我们知道HashMap中经常用到hash()方法. 比如:put()方法中 public V put(K key, V value){if(key==null ...

  3. HashMap中的Hash码怎么计算,为什么要这样做?

    HashMap面试系列(1) Q:HashMap中的Hash码如何计算?为什么要这么做? 注意:HashCode()是对象的Hash码,和HashMap中的Hash码不是同一个东西 1.8版本如下 s ...

  4. 「分布式专题」分布式系统中一致性hash算法

    近年来B2C.O2O等商业概念的提出和移动端的发展,使得分布式系统流行了起来.分布式系统相对于单系统,解决了流量大.系统高可用和高容错等问题.功能强大也意味着实现起来需要更多技术的支持.例如系统访问层 ...

  5. PHP中各种Hash算法性能比较

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html 内部邀请码:C8E245J (不写邀请码,没有现金送) 国 ...

  6. hashmap中的hash扰动函数

    https://www.zhihu.com/question/20733617 转载于:https://www.cnblogs.com/lushilin/p/6142597.html

  7. hash算法_阿里面试官:讲一下Hashmap中hash算法!

    注:本文内容全部基于jdk8讲述. 相信很多人都知道,在JDK8中,HashMap的容量总是2的n次幂,那么这么设计的目的究竟是什么呢?我可不可以将默认的初始容量从16改成20呢,扩容的时候我可不可以 ...

  8. HashMap的工作原理(一):Hash算法

    1.什么是Hash Hash也被称为散列.哈希,对应的英文都是Hash.他们的基本原理都是把任意长度的输入,通过Hash算法变成固定长度的输出.这个映射的规则就是对应的Hash算法,而原始数据映射之后 ...

  9. [区块链] 密码学中Hash算法(基础)

    在介绍Hash算法之前,先给大家来个数据结构中对hash表(散列表)的简单解释,然后我再逐步深入,讲解一下hash算法. 一.Hash原理--基础篇 1.1 概念 哈希表就是一种以 键-值(key-i ...

最新文章

  1. JSON 序列化和反序列化——JavaScriptSerializer实现
  2. SQL DMV功能使用
  3. CentOS7安装ipython
  4. 8大排序算法图文讲解
  5. 各种编程语言的按钮输入框
  6. [Objective-C]编程艺术 笔记整理
  7. Pannellum:实例之全景图预览
  8. Centos--swoole平滑重启服务
  9. 如何购买腾讯云学生服务器
  10. STM32与S3C2440的区别
  11. win10和win8双系统安装
  12. FileBrowser文件浏览器部署
  13. “驱动人生”升级通道传木马,技术分析报告来了
  14. 2020年DDCTF-web签到题题解
  15. javax.servlet.ServletException: Could not resolve view with name ‘***‘ in servlet
  16. 这些Android手机现在支持Fortnite(不仅仅是Samsung!)
  17. 机器人门禁控制盒怎么接线方法_门禁系统接线方法
  18. 利用F检验来检验自变量与因变量之间的关系能否用一个线性回归模型来表示
  19. 如何配置无线路由为交换机模式
  20. 中国石油大学(北京)-《 完井工程》第一阶段在线作业

热门文章

  1. 关于sizeof的一些东西
  2. pringboot后端解决跨域问题
  3. 用nodejs向163邮箱, gmail邮箱, qq邮箱发邮件, nodemailer使用详解
  4. python通过代理自动发邮件脚本_python自动发送邮件脚本
  5. java虚拟机_深入浅出Java虚拟机,从来没有人能把Java 虚拟机讲解的这么透彻
  6. PaddlePaddle Perceptron Example
  7. NHibernate剖析:Mapping篇之Mapping-By-Code(1):概览
  8. leetcode 【 Sort List 】 python 实现
  9. 倒排索引-搜索引擎的基石
  10. Deep learning:十(PCA和whitening)