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 的哈希值是如何计算的,为何这么计算?的更多相关文章
- 【转】HashMap集合中key只能为引用数据类型,不能为基本类型
在HashMap中,为什么不能使用基本数据类型作为key? 其实和HashMap底层的存储原理有关,HashMap存储数据的特点是:无序.无索引.不能存储重复元素. 存储元素采用的是hash表存储数据 ...
- Java - HashMap分别按Key和Value进行排序
我们都知道,Java中的Map结构是key->value键值对存储的,而且根据Map的特性,同一个Map中 不存在两个Key相同的元素,而value不存在这个限制.换句话说,在同一个Map中Ke ...
- Java中String的哈希值计算
下面都是从String类的源码中粘贴出来的 private int hash; // Default to 0 public int hashCode() { int h = hash; if (h ...
- 关于Java读取mysql中date类型字段默认值'0000-00-00'的问题
今天在做项目过程中,查询一个表中数据时总碰到这个问题: java.sql.SQLException:Value '0000-00-00' can not be represented as ...
- 为什么阿里巴巴Java开发手册中强制要求接口返回值不允许使用枚举?
在阅读<阿里巴巴Java开发手册>时,发现有一条关于二方库依赖中接口返回值不允许使用枚举类型的规约,具体内容如下: 在谈论为什么之前先来科普下什么是二方库,二方库也称作二方包,一般指公司内 ...
- Java异常处理场景中不同位置的返回值详细解析
Java 异常处理中的返回值在不同位置不同场景下是有一些差别的,这里需要格外注意 具体分以下两种场景: 1 finally语句块没有return语句,即当代码执行到try或者catch语句块中的ret ...
- JAVA获取oracle中sequences的最后一个值
项目中,用到一个序列作单号,框架用的是ssh,在dao层去拿的时候,运行时报错为dual is not mapped,[select *.nextval nextvalue from dual] 后来 ...
- [翻译]Java HashMap工作原理
大部分Java开发者都在使用Map,特别是HashMap.HashMap是一种简单但强大的方式去存储和获取数据.但有多少开发者知道HashMap内部如何工作呢?几天前,我阅读了java.util.Ha ...
- 【转】Java HashMap工作原理(好文章)
大部分Java开发者都在使用Map,特别是HashMap.HashMap是一种简单但强大的方式去存储和获取数据.但有多少开发者知道HashMap内部如何工作呢?几天前,我阅读了java.util.Ha ...
随机推荐
- 使用EFCore连接Oracle数据库时出现的问题
问题 System.TypeLoadException: Method 'Create' in type 'Oracle.EntityFrameworkCore.Infrastructure.Inte ...
- tcp服务器
如同上面的电话机过程一样,在程序中,如果想要完成一个tcp服务器的功能,需要的流程如下: socket创建一个套接字 bind绑定ip和port listen使套接字变为可以被动链接 accept等待 ...
- 如何设计一个亿级网关(API Gateway)?
1.背景 1.1 什么是API网关 API网关可以看做系统与外界联通的入口,我们可以在网关进行处理一些非业务逻辑的逻辑,比如权限验证,监控,缓存,请求路由等等. 1.2 为什么需要API网关 RPC协 ...
- Vue3.0短视频+直播|vue3+vite2+vant3仿抖音界面|vue3.x小视频实例
基于vue3.0构建移动端仿抖音/快手短视频+直播实战项目Vue3-DouYin. 5G时代已来,短视频也越来越成为新一代年轻人的娱乐方式,在这个特殊之年,又将再一次成为新年俗! 基于vue3.x+v ...
- H3C交换机端口聚合配置
1.接入交换机: interface Ten-GigabitEthernet1/0/21 port link-mode bridge port link-type trunk port trunk p ...
- 数据中心网络技术新贵:VXLAN与园区网络虚拟化
摘要:为了应对传统数据中心网络对服务器虚拟化技术的限制,VXLAN技术应运而生. 1 概述 传统数据中心网络面临的问题 虚拟机规模受设备表项规格限制 在传统二层网络中,交换机通过查询MAC地址表来转发 ...
- The Department of Redundancy Department
Write a program that will remove all duplicates from a sequence of integers and print the list of un ...
- hdu 6703 array(权值线段树)
Problem Description You are given an array a1,a2,...,an(∀i∈[1,n],1≤ai≤n). Initially, each element of ...
- poj3415 Common Substrings (后缀数组+单调队列)
Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 9414 Accepted: 3123 Description A sub ...
- zjnu1707 TOPOVI (map+模拟)
Description Mirko is a huge fan of chess and programming, but typical chess soon became boring for h ...
