Java中HashMap的hash分布策略的简单解释
趴源码是看到一段不可思议的代码,网上的解释似乎不大令人满意,因此稍微花点时间解读了一下,如有错误请指正
HashMap的桶是这样搞的
// 片段1
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
// 片段2
int n = tab.length;
int index = (n - 1) & hash;
index就是最后得到下标,代码很简洁,但问题很多
Q1.我知道&使得index<=min(n-1,hash),但为什么用&不用mod?
A1.n-1是2^m-1,等价于hash mod 2^m = hash mod n,用&和%完全一致,并且&更快,因此没有用%的理由
Q2.我是说你这样&有什么用?
A2.只要保证hash分布足够均衡,也保证了hash后几位也足够均匀,那idx的分布在长度范围内也是分布均匀的
Q3.高16位异或有什么用?
A3.由Q1我们知道idx取决于hash的后log10(n)+1长度的数值分布,那问题来了,当n本身较小时,高位等价于被截断,hash的意义存在局限性(想象一下多个数高位不同低位相同的冲突),因此需要高位的运算参与,尽可能满足最后结果的分布均匀
Q4.那高16位参与运算咋不用&、|?
A4.首先,如果使用&,当长度大于\(2^{16}\)时高16位将全部置零,也就是说空间完全被浪费(你永远算不到那里),下一个|是处于0和1的概率分布而言,1出现的可能比0高得多,也不是好方法
Q5.这样哈希并不一定很靠谱啊?
A5.确实,但源码内部的注释有说明到,由于已经采用了大量哈希碰撞时交由红黑树处理的策略,因此这里的哈希策略只是高性能下比较好的实现,而非严谨的实现
Java中HashMap的hash分布策略的简单解释的更多相关文章
- java集合(2)- java中HashMap详解
java中HashMap详解 基于哈希表的 Map 接口的实现.此实现提供所有可选的映射操作,并允许使用 null 值和 null 键.(除了非同步和允许使用 null 之外,HashMap 类与 H ...
- Java中HashMap的实现原理
最近面试中被问及Java中HashMap的原理,瞬间无言以对,因此痛定思痛觉得研究一番. 一.Java中的hashCode和equals 1.关于hashCode hashCode的存在主要是用于查找 ...
- 【转】 java中HashMap详解
原文网址:http://blog.csdn.net/caihaijiang/article/details/6280251 java中HashMap详解 HashMap 和 HashSet 是 Jav ...
- java中HashMap详解(转)
java中HashMap详解 博客分类: JavaSE Java算法JDK编程生活 HashMap 和 HashSet 是 Java Collection Framework 的两个重要成 ...
- JAVA中hashmap的分析
从http://blog.csdn.net/luanlouis/article/details/41576373?utm_source=tuicool&utm_medium=referral学 ...
- java中HashMap的设计精妙在哪?
摘要:本文结合图解和问题,教你一次性搞定HashMap 本文分享自华为云社区<java中HashMap的设计精妙在哪?用图解和几个问题教你一次性搞定HashMap>,作者:breakDaw ...
- Java中HashMap遍历的两种方式
Java中HashMap遍历的两种方式 转]Java中HashMap遍历的两种方式原文地址: http://www.javaweb.cc/language/java/032291.shtml 第一种: ...
- JAVA中HashMap相关知识的总结(一)
Java中HashMap在jdk1.7和jdk1.8中的区别点: 在jdk1.7中是用数组+链表形式存储,1.8采用数组+链表/红黑树形式 Jdk1.8中由链表转为红黑树是长度大于8,由红黑树转为链表 ...
- java中有界队列的饱和策略(reject policy)
文章目录 AbortPolicy DiscardPolicy DiscardOldestPolicy CallerRunsPolicy 使用Semaphore java中有界队列的饱和策略(rejec ...
随机推荐
- SSL握手通信详解及linux下c/c++ SSL Socket代码举例(另附SSL双向认证客户端代码)
SSL握手通信详解及linux下c/c++ SSL Socket代码举例(另附SSL双向认证客户端代码) 摘自: https://blog.csdn.net/sjin_1314/article/det ...
- POJ2031 Building a Space Station 2017-04-13 11:38 48人阅读 评论(0) 收藏
Building a Space Station Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 8572 Accepte ...
- Vivado安装教程
Vivado的各个版本的安流程其实都差不多,本教程用Vivado2016.4为例进行安装,同样适用于之前和之后的各个版本. 下载好安装包后打开,双击xsetup.exe运行安装程序 弹出的窗口,提示现 ...
- [label][翻译][JavaScript-Translation]七个步骤让你写出更好的JavaScript代码
7 steps to better JavaScript 原文链接: http://www.creativebloq.com/netmag/7-steps-better-javascript-5141 ...
- [label][转载][JavaSript]querySelectorAll 方法相比 getElementsBy 系列方法有什么区别?
轉載出處: http://www.zhihu.com/question/24702250 querySelectorAll 相比下面这些方法有什么区别? getElementsByTagName g ...
- firedac odbc sql server driver连接占线导致另一个hstmt
firedac odbc sql server driver连接占线导致另一个hstmt 原因:FDQuery.FetchOptions.Mode=fmOnDemand.好像是为了性能问题,不设置则默 ...
- oracle 批量删除触发器
--生成删除触发器的语句 select 'drop trigger "'||trigger_name||'";' from all_triggers where TRIGGER_ ...
- 自己从0开始学习Unity的笔记 VII (C#中类继承练习)
好久都没有写了.今天做了类继承的练习,做了一个小队,进行简单的判定. namespace 兵团建立练习 { class ServantBasics { public string name; //pr ...
- 浅谈TCP通讯
基于Tcp协议的Socket通讯类似于B/S架构,面向连接,但不同的是服务器端可以向客户端主动推送消息. 使用Tcp协议通讯需要具备以下几个条件: (1).建立一个套接字(Socket) (2).绑定 ...
- JavaWeb -JDBC使用(数据库-javaweb连接)
使用JDBC四个大类 1. DriverManager:管理jdbc驱动 2. Connection:连接(通过DriverManager产生) 3. Statement/PreparedStatem ...