java hash值怎么生成_2021-2-17:Java HashMap 的中 key 的哈希值是如何计算的,为何这么计算...

2021-2-17:Java HashMap 的中 key 的哈希值是如何计算的,为何这么计算

首先,我们知道 HashMap 的底层实现是开放地址法 + 链地址法的方式来实现。

即数组 + 链表的实现方式,通过计算哈希值,找到数组对应的位置,如果已存在元素,就加到这个位置的链表上。在 Java 8 之后,链表过长还会转化为红黑树。

这个数组并不是一开始就很大,而是随着 HashMap 里面的值变多,达到 LoadFactor 的界限之后,就会扩容。刚开始的数组很小,默认只有 16。

这个数组大小一定是 2 的 n 次方,因为找到数组对应的位置需要通过取余计算,取余计算是一个很耗费性能的计算,而对 2 的 n 次方取余就是对 2 的 n 次方减一取与运算。所以保持数组大小为 2 的 n 次方,这样就可以保证计算位置高效。

那么这个哈希值究竟是怎么计算的呢假设就是用 Key 的哈希值直接计算。假设有如下两个 key,哈希值分别是:

key1:

0000 0000 0010 1111 1001 0000 0110 1101

key2:

0000 0000 0010 0000 1001 0000 0110 1101

如果直接使用数组默认大小,取余之后 key1 与 key2 就会到数组同一个下标。其实 key1 和 key2 的高位是不一样的。

由于数组是从小到达扩容的,为了优化高位被忽略这个问题,HashMap 源码中对于计算哈希值做了优化,采用高位16位组成的数字与源哈希值取异或而生成的哈希值作为用来计算 HashMap 的数组位置的哈希值:

static final int hash(Object key) {

int h;

return (key == null) 0 : (h = key.hashCode()) ^ (h 16);

}

为什么要用异或首先,对于一个数字,转换成二进制之后,其中为的 1 的位置代表这个数字的特性.对于异或运算,如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。0与0异或是0,0与1异或是1,这样相当于让高位的特性在低位得以体现,所以采用这种算法,减少碰撞。

微信搜索“我的编程喵”关注公众号,每日一刷,轻松提升技术,斩获各种offer:

2021-2-17:Java HashMap 的中 key 的哈希值是如何计算的,为何这么计算 相关文章

深入理解 Java 高级特性之反射

什么是反射 在我们学习 Java 之初,我们怎么去写代码 1 Student student = new Student(); 首先我们要创建类的实例化对象,在去调用类的方法、获取值等操作,如果没有这个对象的话,那么我们什么也做不了,例如: 1 package 反射; 2 3 public class Reflecti

Java中的volatile关键字详解

volatile的作用及原理 当一个变量被volatile修饰时,会拥有两个特性: 保证了不同线程对该变量操作的内存可见性.(当一个线程修改了变量,其他使用次变量的线程可以立即知道这一修改). 禁止了指令重排序. 1. 保证内存可见性 JMM操作变量的时候不是直接在主存进行

关于hystrix.contrib.javanica.exception.FallbackDefinitionException: fallback method wasnt found异常

在Spring中使用断路器后可能会遇到:com.netflix.hystrix.contrib.javanica.exception.FallbackDefinitionException: fallback method wasn't found 典例如下: @Servicepublic class OrderService {@AutowiredRestTemplate restTemplate;@HystrixCommand(fa

Java并发之ThreadPoolExecutor源码解析(一)

线程池 假设我们编写了一个Servlet应用,当用户通过浏览器发起一个请求到达我们服务器时,传统的Servlet应用一般针对一个用户请求创建一个线程去执行请求,等到请求执行完毕后,再销毁线程。这种设计在用户量几百或者几千的情况下一般不会有什么大问题,但是

顺序结构,选择结构

顺序结构 ◆ JAVA的基本结构就是顺序结构,除非特别指明,否则就按照顺序一句一句执行。 ◆ 顺序结构是最简单的算法结构。 ◆ 语句与语句之间,框与框之间是按从上到下的顺序进行的,它是由若干个依次执行的处理步骤组成的, 它是任何一个算法都离不开的一种

java学习阶段一 继承 注解

# java学习阶段一 继承 注解## 介绍继承是一种类与类之间的关系使用已存在的类的定义作为基础建立新类子类(派生类)继承父类(基类)子类 可以有自己的新功能 不可以**选择性**的继承父类中的成员## 基本知识* 继承的实现 使用extends关键字在类声明部分 ``

Java中继承详解

继承 继承的关键字---extends super super调用父类的构造方法,必须在构造方法的第一个 super必须只能出现在子类的方法或者构造方法中! super和this不能同时调用构造方法! super VS this 前提 this:没有继承又可以使用它 super:只能在继承条件下使用 代

Java switch case 语句

文章搬运,原文链接 switch case 语句判断一个变量与一系列值中某个值是否相等, 每个值称为一个分支 。 语法 switch case 语句语法格式如下: switch(expression){ case value : //语句 break; //可选 case value : //语句 break; //可选 //你可以有任意数

java学习阶段一 单例化

java学习阶段一 单例化 介绍 设计模式时基于场景的解决方案 是面对一些难题中前辈们提供的和为人们认可的解决方案 基本知识 介绍其中一个模式 单例模式:使得该类中的一个对象成为该类系统中唯一的实例 要点 1 某个类只能有一个实例 2 必须自行创建实例 3 必

JSON与AJAX

JSON JSON JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析与生成 JSON采用完全独立于语言的文本格式,并且很多语言都支持json(C,C++,C#,Java,JavaScript...) JSON的格式就是key:value形式,类似

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值