HashMap中(tab.length - 1) & hash的神奇之处

在HashMap和ConcurrentHashMap的源码中,作者通过:

int index = (tab.length - 1) & hash;

来计算将要插入的元素在数组中的索引位置。这样做有什么妙处呐?

1、保证不会发生数组越界

首先我们要知道,在HashMap和ConcurrentHashMap中,数组的长度按规定一定是2的幂(2的n次方)。

因此,数组的长度的二进制形式是:10000...000, 1后面有偶数个0。
那么,tab.length - 1 的二进制形式就是01111.111, 0后面有偶数个1。最高位是0, 和hash值相“与”,结果值一定不会比数组的长度值大,因此也就不会发生数组越界。

2、保证元素尽可能的均匀分布

由上边的分析可知,tab.length一定是一个偶数,tab.length - 1一定是一个奇数。

假设现在数组的长度(tab.length)为16,减去1后(tab.length - 1)就是15,15对应的二进制是:1111。

现在假设有两个元素需要插入,一个哈希值是8,二进制是1000,一个哈希值是9,二进制是1001。和1111“与”运算后,结果分别是1000和1001,它们被分配在了数组的不同位置,这样,哈希的分布非常均匀。

那么,如果数组长度是奇数呢?减去1后(tab.length - 1)就是偶数了,偶数对应的二进制最低位一定是 0,例如14二进制1110。对上面两个数子分别“与”运算,得到1000和1000。结果都是一样的值。那么,哈希值8和9的元素都被存储在数组同一个index位置的链表中。在操作的时候,链表中的元素越多,效率越低,因为要不停的对链表循环比较。

所以,一定要使哈希均匀分布,尽量减少哈希冲突,提高效率。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • HashMap 是 Java 面试必考的知识点,面试官从这个小知识点就可以了解我们对 Java 基础的掌握程度。网...
    野狗子嗷嗷嗷阅读 6,780评论 9 107
  • 一、基本数据类型 注释 单行注释:// 区域注释:/* */ 文档注释:/** */ 数值 对于byte类型而言...
    龙猫小爷阅读 4,403评论 0 16
  • 经国务院批准,现将2017年元旦、春节、清明节、劳动节、端午节、中秋节和国庆节放假调休日期的具体安排通知如下。 一...
    123逍遥游阅读 262评论 0 0
  • 河面上滑过一对对水鸟和野鸭 谁在等待,远方的离人 眼看着太阳一点点坠落 谁在吟唱,有爱的诗句 世界就在那里 冷冷清...
    冷暖有桃花阅读 223评论 0 0
  • 毕业你好,久仰大名。一直都知道你终将出现在我的生命中,却不曾想你来的这么快,也许是你太过劳累,到我这里时甚至都忘记...
    罗小伟阅读 251评论 0 0

友情链接更多精彩内容