hashmap为什么是2的倍数_HashMap扩容大小为什么是2的幂

news/2024/8/26 16:20:51

1、前言

在回答这个问题之前,我们可以回顾一下HashMap的存取过程,当执行putVal的操作的时候,

首先检查大小,看是否需要扩容(默认元素超过最大值的0.75时扩容),如果需要扩容就进行扩容

然后计算出key的hashcode,根据hashcode定位数值所在的bucketIndex

如果该位置上没有元素,就直接插入,结束

如果该位置上有元素就使用equal比较是否相同

如果key相同就把新的value替换旧的value,结束

如果key不同,就继续遍历,找到根节点,如果没找到key的话,就构造一个新的节点,然后把节点插入到链表尾部,表示put成功(jdk 1.8 之后链表长度超过阈值就会转化为红黑树)

2、详解

好了,一个put操作就这样完成了,按照我们理想的状况,hashMap的存取就是O(1),也就是直接根据hashcode就可以找到它,每个bucket只存储一个节点,链表指向都是null,这样就比较开心了,不要出现一个链表很长的情况。

所以我们希望它能分布的均匀一点,如果让我们设计的话,我们肯定是直接对长度取模-----hashcode % length,但HashMap的设计者却不是这样写的,它写成了2进制运算,如下:

static final int hash(Object key) {

int h;

return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);

}

index = (n - 1) & hash

为什么设计成(n - 1) & hash 这样呢?在 n 为 2次幂的情况下时,(n - 1) & hash ≈ hash % n ,因为2进制的运算速度远远高于取模,所以就使用了这种方式,所以要求为2的幂。

我们可以看到它求hash的过程,将32位的hashCode值向右移动16位,高位补0,也就是只要了高16位,这是为什么呢?因为hashcode的计算方法导致哈希值的差异主要在高位,而 (n - 1) & hash是忽略了容量以上的高位的,所以 使用h >>>16就是为了避免类似情况的哈希冲突


http://www.niftyadmin.cn/n/1999035.html

相关文章

zlggui菜单12864_悠景双色12864OLED驱动+ZLGGUI简单移植,有图有真相

最近也做了个OLED的温度计,方案是ZLG Easy ARM113818B202.4OLED双色屏LT3465本来想等CP2102的USB转串口做完,可以在电脑上记录分析温度以后才传方案,现在既然楼主先贴了,那我也来凑凑热闹吧。(原文件名:Photo_0001.jpg)(原文件名:…

VC制作类似于IE4的酷工具条

VC制作类似于IE4的酷工具条 用VC制作工具条的方法很多,本文提供一种制作类似于IE4.0的工具条。能实现鼠标移上图标时,图标变为彩色,在工具条的位置,能停摆几种工具条。具体原理解释见步骤过程。步骤如下:1.…

【Amaple教程】2. 模块

正如它的名字&#xff0c;模块用于amaplejs单页应用的页面分割&#xff0c;所有的跳转更新和代码编写都是以模块为单位的。 定义一个模块 一个模块由<module>标签对包含&#xff0c;内部分为template模板、JavaScript和css三部分&#xff0c;像这样&#xff1a; <modu…

以下哪个变量可以做python的变量_Python 中,以下哪个变量的赋值是正确的?

摘要&#xff1a;行室在进站的外基调整覆盖时&#xff0c;中值正确向化方、中值正确增以“压制强室外”为优室内&#xff0c;系统改调整结合必须的整分布室内&#xff0c;系统染问题频污已有的高处理层导分布室内。染引钙污钻井液黏起的切力度、中值正确升高&#xff0c;效果加…

echart只显示前几_开箱篇:首测27英寸飞利浦显示器,有大屏的味道

随着智能时代的崛起&#xff0c;电脑以及周边产品的使用率越来越低。此前还有有网友在讨论&#xff0c;以后的智能手机会不会替代电脑呢&#xff1f;当然&#xff0c;这只是部分网友的看法&#xff0c;在我看来这个可能性并不大&#xff0c;因为手机的屏幕太小了&#xff0c;先…

VC在windows下编写用于串行通讯的程序

VC在windows下编写用于串行通讯的程序 既然有这么多人问这个文体&#xff0c;贝贝就给个Visual C 4.2写的 Window 95串口通讯函数集合(只适用于32位) 需要说明的是&#xff1a;这是我程序的一部分&#xff0c;因此有一些与具体应用无关的部分。 但我觉得关键是原理&#xff0…

centos 7安装galera的小注意

2019独角兽企业重金招聘Python工程师标准>>> 因为centos 7自带的mysqllib跟之前的不同&#xff0c;所以你用rpm -qa | grep mysql是查不到的&#xff0c;所以要查找的其实是这个mariadb-libs,所以我们要卸载的其实是这个库&#xff0c;否则你的server是装不上的。yu…

java awt 背景_Java开发- Swing AWT-设置背景图片 | 学步园

Java设置背景图片如何使用纯正的 JAVASE 设置一个界面的背景图片呢?import java.awt.*;import javax.swing.*;public class TestLogin {JFrame jf new JFrame("[欢迎进入银行自助系统]");JLabel lb0 new JLabel(" 银 行 自 助 终 端");JLabel lb1 new …