【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 = ...
随机推荐
- 第11节-BLE协议HCI层的硬件接口
本篇博客由韦东山视频整理所得 如何控制链路层让其发出广播包.数据包?通过HCI层向它发出命令,也可以通过ATT层.L2CAP层向LL层发出数据. 学习资料: 蓝牙协议core_v5.0.pdf < ...
- contact form 7如何搭配Akismet过滤垃圾邮件
contact form 7有很多站长在用,但是经常会有一些垃圾邮件进来,如何过滤呢?两个方法:1.表单提交启用验证码功能,很多垃圾邮件是用软件扫相应的端口,然后批量群发,如果用验证码了可以过滤很大一 ...
- gitlab的搭建和使用(转)
工作当中常用的GitHub比较好用,但是安全性不是太强,因为github完全开源的,安全性不高 有空搞一下,先记录几个博客 https://yq.aliyun.com/articles/44531 h ...
- 某模拟赛C题 树上路径统计 (点分治)
题意 给定一棵有n个节点的无根树,树上的每个点有一个非负整数点权.定义一条路径的价值为路径上的点权和-路径上的点权最大值. 给定参数P,我!=们想知道,有多少不同的树上简单路径,满足它的价值恰好是P的 ...
- [TJOI2009]猜数字(洛谷 3868)
题目描述 现有两组数字,每组k个,第一组中的数字分别为:a1,a2,...,ak表示,第二组中的数字分别用b1,b2,...,bk表示.其中第二组中的数字是两两互素的.求最小的非负整数n,满足对于任意 ...
- 【Gamma】Scrum Meeting 7
前言 会议定点:大运村公寓 会议时间:2019/6/5 会议目的:明确下阶段目标 一.任务进度 组员 上周任务进度 下阶段任务 大娃 修复后端bug 辅助做好引导录屏 二娃 撰写会议博客 撰写会议博客 ...
- 【IntelliJ IDEA学习之三】IntelliJ IDEA常用快捷键
版本:IntelliJIDEA2018.1.4 按场景列举一.打开设置CTRL + ALT + S:打开设置(File-->Settings...)Ctrl + Shift + Alt + S: ...
- 命名法:骆驼(Camel)、帕斯卡(pascal)、匈牙利(Hungarian)、下划线(_)
首先欢迎大家到来! 常用的命名法:骆驼(Camel).帕斯卡(pascal).匈牙利(Hungarian).下划线(_) 骆驼:是指混合使用大小写字母来构成变量和函数的名字 帕斯卡:与骆驼命名法类似只 ...
- 通过URI协议实现浏览器调用手机app
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
- ubuntu 17.04 下搭建深度学习环境
.目前使用CPU即可,先不需要显卡配置 .使用pip3 安装深度学习框架 .要先安装pip3 #sudo apt install python3-pip https://blog.csdn.net/b ...