一、简介

大家都知道,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算法的更多相关文章

  1. HashMap中的hash算法总结

    前言 算法一直是我的弱项,然而面试中基本是必考的项目,刚好上次看到一个HashMap的面试题,今天也来学习下 HashMap中的hash算法是如何实现的. 数学知识回顾 << : 左移运算 ...

  2. HashMap中的hash算法中的几个疑问

    HashMap中哈希算法的关键代码 //重新计算哈希值 static final int hash(Object key) { int h; return (key == null) ? 0 : (h ...

  3. hashCode及HashMap中的hash()函数

    一.hashcode是什么 要理解hashcode首先要理解hash表这个概念 1. 哈希表 hash表也称散列表(Hash table),是根据关键码值(Key value)而直接进行访问的数据结构 ...

  4. [ 转载 ]hashCode及HashMap中的hash()函数

    hashCode及HashMap中的hash()函数   一.hashcode是什么 要理解hashcode首先要理解hash表这个概念 1. 哈希表 hash表也称散列表(Hash table),是 ...

  5. HashMap 中的 hash 函数

    1. 什么是 hash 函数 hash 函数,即散列函数,或叫哈希函数.它可以将不定长的输入,通过散列算法转换成一个定长的输出,这个输出就是散列值.需要注意的是,不同的输入通过散列函数,也可能会得到同 ...

  6. HashMap中的hash函数

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

  7. 图像相似度中的Hash算法

           度量两张图片的相似度有许多算法,本文讲介绍工程领域中最常用的图片相似度算法之一--Hash算法.Hash算法准确的说有三种,分别为平均哈希算法(aHash).感知哈希算法你(pHash) ...

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

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

  9. php中各种hash算法的执行速度比较

    更多内容推荐微信公众号,欢迎关注: PHP中的Hash函数很多,像MD4.MD5.SHA-1.SHA-256.SHA-384.SHA-512等我们比较常见,那么各个哈希的执行速度呢? $algos = ...

随机推荐

  1. Iconfont技术

    什么是 IconFont 顾名思义,IconFont 就是字体图标.严格地说,就是一种字体,但是,它们不包含字母或数字,而是包含符号和字形.您可以使用 CSS 设置样式,就像设置常规文本一样,这使得 ...

  2. Python多线程采集百度相关搜索关键词

    百度相关搜索关键词抓取,读取txt关键词,导出txt关键词 #百度相关搜索关键词抓取,读取txt关键词,导出txt关键词   # -*- coding=utf-8 -*- import request ...

  3. 【AICC】2019训练营笔记

    1.AI 人工的方法在机器上实现智能:机器学习.计算机视觉.规划决策.自然语言处理.认知推理.高效搜索 2.三大学派 符号主义 连接主义:CNN 行为主义 3.两条路线 结构模仿 功能模仿 4.AI芯 ...

  4. GIL全局解释器锁及协程

    GIL全局解释器锁 1.什么是GIL全局解释器锁 GIL本质是一把互斥锁,相当于执行权限,每个进程内都会存在一把GIL同一进程内的多线程,必须抢到GIL之后才能使用Cpython解释器来执行自己的代码 ...

  5. 洛谷 P2661 信息传递(NOIP 提高 2015)

    传送门 本题本来是一个很好的并查集的题(似乎靠的就是并查集),然而蒟蒻我刚刚学习了 tarjan 所以就用 terjan做了一下 大概题意就是:一个人要和另外的一个人告诉他所知道的信息,然后问什么时候 ...

  6. 11-散列3 QQ帐户的申请与登陆 (25 分)

    实现QQ新帐户申请和老帐户登陆的简化版功能.最大挑战是:据说现在的QQ号码已经有10位数了. 输入格式: 输入首先给出一个正整数N(≤10^​5​​),随后给出N行指令.每行指令的格式为:“命令符(空 ...

  7. Python网络爬虫神器PyQuery的使用方法

    #!/usr/bin/env python # -*- coding: utf-8 -*- import requests from pyquery import PyQuery as pq url ...

  8. Redis读写分离技术解析

    背景 云数据库Redis版不管主从版还是集群规格,replica作为备库不对外提供服务,只有在发生HA的时候,replica提升为master后才承担读写流量.这种架构读写请求都在master上完成, ...

  9. jquery设置bootstrap-select的默认选中值

    <select id="mSelect"></select> $("#mSelect").val(["1",&quo ...

  10. spark 通过keytab 获取认证

    /usr/local/spark--bin--cdh5.8.0/bin/spark-submit \ --keytab /home/jj/tl.keytab \ --principal vf@FC.C ...