我们都知道,hashMap在实现的时候,为了寻找在数组上的位置,主要做了两件事

int hash = hash(key);
int i = indexFor(key, table.length);

这个时候得到i才是数组上的位置。

这两个方法详解如下

JDK8对扰动函数的修改,只进行了一次移位(又移16bit),再和key.hashCode()做异或,如图

     static final int hash(Object key){
         int h;
         return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
     }

这个散列值是不能直接拿来用的。用之前还要先做对数组的长度取模运算,得到的余数才能用来访问数组下标。源码中模运算是在这个indexFor( )函数里完成的。

bucketIndex = indexFor(int h, table.length);

其中IndexFor代码

1 static int indexFor(int h, int length){
2     return h & (length - 1);
3 }

indexFor代码,正好解释了为什么HashMap的数组长度要取2的整次幂。因为这样(数组长度-1)正好相当于一个“低位掩码”。“与”操作的结果就是散列值的高位全部归零,只保留低位值,用来做数组下标访问。以初始长度16为例,16-1=15。2进制表示是00000000 00000000 00001111。和某散列值做“与”操作如下,结果就是截取了最低的四位值。

但这时候问题就来了,这样就算我的散列值分布再松散,要是只取最后几位的话,碰撞也会很严重。更要命的是如果散列本身做得不好,分布上成等差数列的漏洞,恰好使最后几个低位呈现规律性重复,就无比蛋疼。

这时候“扰动函数”的价值就体现出来了,说到这里大家应该猜出来了。看下面这个图,

右位移16位,正好是32bit的一半,自己的高半区和低半区做异或,就是为了混合原始哈希码的高位和低位,以此来加大低位的随机性。而且混合后的低位掺杂了高位的部分特征,这样高位的信息也被变相保留下来。

JDK 7做了4次右移,估计是边际效应的原因,JDK8就只做了一次右移。

另外 JDK8在链表长度超过8的时候,就使用红黑树做存储。这一改变大大优化了很多性能。

转载于:https://www.cnblogs.com/lycroseup/p/7344321.html

HashMap之扰动函数和低位掩码相关推荐

  1. jdk1.8中HashMap扰动函数及数组长度为什么是2的n次方介绍

    文章目录 前言 一.什么是二进制? 二.计算机采用二进制的原因 三.十进制与二进制相互转换 十进制转成二进制 二进制转换为十进制 与.或.异或运算 按位异或 按位与运算 按位或运算 Jdk1.8中Ha ...

  2. HashMap中的hash函数

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

  3. 面试:说说你对 HashMap 的认识?

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 1 概述 HashMap是基于哈希表实现的,每一个元素是 ...

  4. 【Java自顶向下】HashMap面试题(2021最新版)

    文章目录 1.HashMap的底层数据结构? 2.为啥需要链表,链表又是怎么样子的呢? 3.新的Entry节点在插入链表的时候,是怎么插入的么? 4.Java7中的HashMap和Java8中的Has ...

  5. hashmap remove 没释放内存_面试题:来,问你几个关于HashMap的问题?

    作者:阿进的写字台 来源:https://www.cnblogs.com/homejim/p/10029796.html 1.HashMap在JAVA中的怎么工作的? 基于Hash的原理. 2.什么是 ...

  6. HashMap是如何工作的

    2019独角兽企业重金招聘Python工程师标准>>> 1 HashMap在JAVA中的怎么工作的? 基于Hash的原理 2 什么是哈希? 最简单形式的 hash,是一种在对任何变量 ...

  7. 【JDK1.8】Java HashMap实现细节

    底层是用数组实现的 /*** The table, initialized on first use, and resized as* necessary. When allocated, lengt ...

  8. hashmap扩容机制_图文并茂:HashMap经典详解!

    点击上方 Java后端,选择 设为星标 优质文章,及时送达 代码中的注解多看几遍,其中HashMap的扩容机制是要必懂知识!结合图片一起理解! 什么是 HashMap? HashMap 是基于哈希表的 ...

  9. hashmap remove 没释放内存_java从零开始手写 redis(13)HashMap 源码原理详解

    为什么学习 HashMap 源码? 作为一名 java 开发,基本上最常用的数据结构就是 HashMap 和 List,jdk 的 HashMap 设计还是非常值得深入学习的. 无论是在面试还是工作中 ...

最新文章

  1. 崩溃!双十一第 4 天,某互联网公司黄了?
  2. springcloud 相同服务名_Spring 微服务从入门到入土
  3. laravel 分词搜索匹配度_elasticsearch基础笔记9-elasticsearch 词项全文搜索
  4. Java笔记-spring-rabbitmq中queue设置argument(添加x-message-ttl)
  5. 服务器端的JavaScript
  6. 运算除法的计算机函数,2、Python基础--除法、常用数学函数(示例代码)
  7. 编写贩卖《和平精英》游戏外挂,5人被判刑;苹果推出轻App码;Firefox 84.0发布|极客头条...
  8. seci-log 1.06 发布 增加全文搜索
  9. SourceAnalysis/Binder源码分析.md
  10. android 电视安装apk,给一切安卓智能电视安装第三方软件市场
  11. PDF.js 在线pdf阅读插件(禁止打印,下载,每页水印)
  12. hdu5855二分+最大流
  13. go语言 json -转载
  14. 获取文本文件编码与导出源代码
  15. “国民记忆”品牌的年轻化战略,从换掉王力宏开始?
  16. Rancher入门到精通-2.0 pening storage failed: block open /prometheus/meta.json: no such file or directory
  17. AD17如何将图片转化为PCB图片丝印,定制你的专属logo!
  18. 在线安装gem5和nvmain集成gem5
  19. android app代码审计,常规漏洞/缺陷整理(持续更新)
  20. 首选DNS服务器地址不显示,首选dns服务器如何设置?如何设置DNS地址

热门文章

  1. Spring Cloud —— 链路追踪技术
  2. 排序算法 —— 堆排序
  3. JDBC——实现通用的查询
  4. java 异步调用webapi_Async Await异步调用WebApi
  5. java 1000到9999_java – 可以0.99999999999乘以四舍五入到1.0?
  6. php ip2long bug,PHP代码ip2long 循环有关问题
  7. mysql not exists很慢_查询速度优化用not EXISTS 代替 not in
  8. requests由于系统缓冲区空间不足_系统C盘满了空间不足的扩容?
  9. python实现qq登录界面_使用Python编写一个QQ办公版的图形登录界面!
  10. 4乘4方格走的路线_苏州周边4个冷门自驾游路线景点推荐