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 ...
随机推荐
- Android应用开发环境的搭建和使用
主要包括Android SDK.Android开发工具:也包括如何使用Android提供的ADB.DDMS.AAPT.DX等工具,掌握这些工具是开发Android应用的基础技能. 1.Android的 ...
- R语言中 fitted()和predict()的区别
fitted是拟合值,predict是预测值.模型是基于给定样本的值建立的,在这些给定样本上做预测就是拟合.在新样本上做预测就是预测. 你可以找一组数据试试,结果如何. fit<-lm(weig ...
- Redis数据结构(三)
Redis五种数据类型: (1)字符串 (2)字符串列表 (3)有序字符串集合 (4)哈希 (5)字符串集合 其中(4)(5)应用最多. key命名的注意: (1)不要过长,尽量不要超过1024,会降 ...
- Max Sum -- hdu -- 1003
链接: http://acm.hdu.edu.cn/showproblem.php?pid=1003 Time Limit: 2000/1000 MS (Java/Others) Memory ...
- JAVA常见面试题及解答
JAVA相关基础知识1.面向对象的特征有哪些方面 1.抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解全部问题,而只是选择其中的一部分,暂时 ...
- Asp.NetCore Razor 模式 Web 应用
Razor 页面是 ASP.NET Core MVC 的一个新功能,它可以使基于页面的编码方式更简单高效. Razor 页面是 ASP.NET Core 2.0 中的一个新选择,它是基于页面的编程模型 ...
- 采购文件中 RFI、RFQ、RFP、IFB的区别
[PMBOK的描述] 采购文件用于征求潜在卖方的建议书.如果主要依据价格来选择卖方(如购买商业或标准产品时),通常就使用标书.投标或报价等术语.如果主要依据其他考虑(如技术能力或技术方法)来选择卖方, ...
- Spring AOP详解(转载)所需要的包
上一篇文章中,<Spring Aop详解(转载)>里的代码都可以运行,只是包比较多,中间缺少了几个相应的包,根据报错,几经百度搜索,终于补全了所有包. 截图如下: 在主测试类里面,有人怀疑 ...
- .NET框架源码解读之SSCLI编译过程简介
前文演示了编译SSCLI最简便的方法(在Windows下): 在“Visual Studio 2005 Command Prompt”下,进入SSCLI的根目录: 运行 env.bat 脚本准备环境: ...
- Python笔记之format()格式输出全解
格式化输出:format() format():把传统的%替换为{}来实现格式化输出 使用位置参数:就是在字符串中把需要输出的变量值用{}来代替,然后用format()来修改使之成为想要的字符串,位置 ...