【Java深入研究】11、深入研究hashmap中的hash算法
一、简介
大家都知道,HashMap中定位到桶的位置 是根据Key的hash值与数组的长度取模来计算的。
JDK8中的hash 算法:
- static final int hash(Object key) {
- int h;
- return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
- }
取模算法:
- hash(key)&(length-1)
二、深入分析
1、取模算法为什么用的是位与运算?
由于位运算直接对内存数据进行操作,不需要转成十进制,因此处理速度非常快。
对2的倍数取模,只要将数与2的倍数-1做按位与运算即可。
对原理感兴趣的可以参考【Java基础】14、位与(&)操作与快速取模
2、为什么不直接使用key.hashcode()进行取模运算?
我们知道hash的目的是为了尽量分布均匀。
取模做位与运算的时候,实际上刚刚开始数组的长度一般比较小,只利用了低16位,高16位是用不到的。这种情况下,产生hash冲突的概率会大大增加。
这样设计保证了对象的hashCode的高16位的变化能反应到低16位中,相比较而言减少了hash冲突的情况 。
选用亦或的方式是因为&和|都会使得结果偏向0或者1 ,并不是均匀的概念。
3、String的hashCode()深入分析
- public int hashCode() {
- int h = hash;
- if (h == 0 && value.length > 0) {
- char val[] = value;
- for (int i = 0; i < value.length; i++) {
- h = 31 * h + val[i];
- }
- hash = h;
- }
- return h;
- }
推导出的公式如下:
- s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
举个例子推导计算一下:
- 假设 n=3
- i=0 -> h = 31 * 0 + val[0]
- i=1 -> h = 31 * (31 * 0 + val[0]) + val[1]
- i=2 -> h = 31 * (31 * (31 * 0 + val[0]) + val[1]) + val[2]
- h = 31*31*31*0 + 31*31*val[0] + 31*val[1] + val[2]
- h = 31^(n-1)*val[0] + 31^(n-2)*val[1] + val[2]
3.1、为什么使用31作为计算的因子呢?
- 选择质数作为乘子,会大大降低hash冲突的概率。质数的值越大,hash冲突率越低
- 31参与乘法运算,可以被 JVM 优化,
31 * i = (i << 5) - i
- 使用 101 计算 hash code 容易导致整型溢出,导致计算精度丢失
【Java深入研究】11、深入研究hashmap中的hash算法的更多相关文章
- HashMap中的hash算法总结
前言 算法一直是我的弱项,然而面试中基本是必考的项目,刚好上次看到一个HashMap的面试题,今天也来学习下 HashMap中的hash算法是如何实现的. 数学知识回顾 << : 左移运算 ...
- HashMap中的hash算法中的几个疑问
HashMap中哈希算法的关键代码 //重新计算哈希值 static final int hash(Object key) { int h; return (key == null) ? 0 : (h ...
- hashCode及HashMap中的hash()函数
一.hashcode是什么 要理解hashcode首先要理解hash表这个概念 1. 哈希表 hash表也称散列表(Hash table),是根据关键码值(Key value)而直接进行访问的数据结构 ...
- [ 转载 ]hashCode及HashMap中的hash()函数
hashCode及HashMap中的hash()函数 一.hashcode是什么 要理解hashcode首先要理解hash表这个概念 1. 哈希表 hash表也称散列表(Hash table),是 ...
- HashMap 中的 hash 函数
1. 什么是 hash 函数 hash 函数,即散列函数,或叫哈希函数.它可以将不定长的输入,通过散列算法转换成一个定长的输出,这个输出就是散列值.需要注意的是,不同的输入通过散列函数,也可能会得到同 ...
- HashMap中的hash函数
在写一个HashSet时候有个需求,是判断HashSet中是否已经存在对象,存在则取出,不存在则add添加.HashSet也是通过HashMap实现,只用了HashMap的key,value都存储一个 ...
- 图像相似度中的Hash算法
度量两张图片的相似度有许多算法,本文讲介绍工程领域中最常用的图片相似度算法之一--Hash算法.Hash算法准确的说有三种,分别为平均哈希算法(aHash).感知哈希算法你(pHash) ...
- PHP中各种Hash算法性能比较
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...
- php中各种hash算法的执行速度比较
更多内容推荐微信公众号,欢迎关注: PHP中的Hash函数很多,像MD4.MD5.SHA-1.SHA-256.SHA-384.SHA-512等我们比较常见,那么各个哈希的执行速度呢? $algos = ...
随机推荐
- 第05组 Beta冲刺(2/4)
第05组 Beta冲刺(2/4) 队名:天码行空 组长博客连接 作业博客连接 团队燃尽图(共享): GitHub当日代码/文档签入记录展示(共享): 组员情况: 组员1:卢欢(组长) 过去两天完成了哪 ...
- Speech Enhancement via Deep Spectrum Image Translation Network
文中提出了一种深度网络来解决单通道语音增强问题. 链接:https://arxiv.org/abs/1911.01902 简介 因为背景噪声和混响的存在,录音通常会被扭曲,会对后端的语音识别等技术产生 ...
- MongoDB executionStats 详细分步查询计划与分步时间(转载)
mongodb性能分析方法:explain() 为了演示的效果,我们先来创建一个有200万个文档的记录.(我自己的电脑耗了15分钟左右插入完成.如果你想插更多的文档也没问题,只要有耐心等就可以了.) ...
- Pandas | 09 迭代
Pandas对象之间的基本迭代的行为取决于类型.当迭代一个系列时,它被视为数组式,基本迭代产生这些值.其他数据结构,如:DataFrame和Panel,遵循类似惯例,迭代对象的键. 简而言之,基本迭代 ...
- Pandas | 04 Panel 面板
面板(Panel)是3D容器的数据.面板数据一词来源于计量经济学,部分源于名称:Pandas - pan(el)-da(ta)-s. 3轴(axis)这个名称旨在给出描述涉及面板数据的操作的一些语义. ...
- 请描述一下cookies、sessionStorage、localStorage、session四者的区别?
存储大小: cookie在4K以内. sessionStorage和localStorage在5M以内. 有效时间: cookie:如果未设置过期时间,关闭浏览器时清空:如果设置了有效时间则在到期后清 ...
- PCM存储格式 Intel 和 Motorola
https://blog.csdn.net/cxz_yzxkj/article/details/84496614
- C语言实现linux之who功能
/* who_test.c */ #include<stdio.h> #include<string.h> #include<getopt.h> #include& ...
- Makefile文件基本格式
以下是Makefile的基本模板 #指定编译器CC = g++#指定编译参数CFLAGS = -std=c++11 #指定头文件路径,此处用于指定非标准库的头文件路径INC = -I./ -I /us ...
- jQuery前端生成二维码
引用: <script src="assets/js/jquery.qrcode.min.js" charset="UTF-8"></scri ...