HashMap的初始化,到底都做了什么?

HashMap初始化参数都是什么?默认是多少?

为什么建议初始化设置容量?

tableSizeFor方法是做什么的?

如何获取到一个key的hash值?及计算下标?

HashMap初始化参数都是什么?默认是多少?

HashMap初始化参数分别是初始容量和负载因子。

初始容量(threshold):默认 16, 必须是2的幂, 最大容量为 1 << 30

负载因子(loadFactor):是指哈希表的负载因子,当哈希表的长度大于capacity * loadFactor时会进行扩容,默认 0.75f

为什么建议初始化设置容量

这块涉及到HashMap的扩容, 在阿里巴巴Java开发手册中已经说明了原因。主要是为了减少频繁的扩容造成的资源损耗。

tableSizeFor方法是做什么的?

初始化HashMap时, 如果传入初始容量, 在初始化时会调用 tableSizeFor(initialCapacity) 方法寻找大于等于当前值的下一个2的幂值.

代码如下:

static final int tableSizeFor(int cap) {
int n = cap - 1; // -1操作, 防止当cap正好是2的幂时的处理
n |= n >>> 1; // n无符号右移1位, 然后和n做 | 运算, (1|0=1 1|1=1 0|0=0 0|1=1)
n |= n >>> 2; // n无符号右移2位, 然后和n做 | 运算,
n |= n >>> 4; // n无符号右移4位, 然后和n做 | 运算,
n |= n >>> 8; // n无符号右移8位, 然后和n做 | 运算,
n |= n >>> 16; // n无符号右移16位, 然后和n做 | 运算, // 最后获得的结果为 cap-1的下一个2的幂值-1, 只需要对n+1即可
return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}
  1. 假设cap值为100, 即0110 0100
  2. cap的下一个2的幂为 0111 1111 即 1000 0000
  3. 0000 = 0111 1111 + 1
  4. 只需要考虑将 首个为1的最高位之后的值置为1, 然后+1即可
  5. 为防止cap本来就是2的幂, 则需要先进行减一操作

如图所示:

最后执行的结果进行加1即可

如何获取到一个key的hash值?

static final int hash(Object key) {
int h;
// key的hashCode ^ 上自己的高16位, 如果是null的话则hash为0
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

获取到了hash值, 那如何计算在数组的那个位置呢?

// n为数组长度  数组下标
i = (n - 1) & hash

数组长度都是 2的幂

假设 n = 1 >> x

则 n - 1 则表示 一个低x位全为1的数

(n - 1) & hash 则相当于 一个低x位全为1的数和hash做&操作.

通过图可以看出, 参与运算的只有低x位, 相当于之前的所有值都不会有效. 所以前面的hash(key) 将key.hashCode()高低16位做^操作, 可以保证, 高低16位都能参与运算.一定程度上避免hash碰撞.在源码注释中已经说明, 是肯定会有碰撞, 但是这是权衡之后的结果.

HashMap的初始化,到底都做了什么?的更多相关文章

  1. HashMap 和 HashTable 到底哪不同 ?

    HashMap 和 HashTable 到底哪不同 ? 2017/05/29 | 分类: 基础技术 | 1 条评论 | 标签: HASHMAP, HASHTABLE 分享到: 原文出处: 程序员赵鑫 ...

  2. Java对象的创建 —— new之后JVM都做了什么?

    Java对象创建过程 1. 类加载检查 虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载.解析和初始化过.如果没 ...

  3. 从架构演进的角度聊聊Spring Cloud都做了些什么?

    Spring Cloud作为一套微服务治理的框架,几乎考虑到了微服务治理的方方面面,之前也写过一些关于Spring Cloud文章,主要偏重各组件的使用,本次分享主要解答这两个问题:Spring Cl ...

  4. java突破------一撸到底(做Java开发,遇到瓶颈是保持现状还是寻求突破?)

    java突破------一撸到底(做Java开发,遇到瓶颈是保持现状还是寻求突破?) 很多人做Java开发2.3年之后,都会觉得自己遇到了瓶颈.什么都会又什么都不会,如何改变困境,为什么很多人写了7. ...

  5. 7.学完linux系统运维到底可以做什么?

    linux运维到底可以做什么?(略有改动原文.排版) 运维,很容易从字面理解为运营.维护. 很多朋友认为,在互联网公司中linux系统运维的工作就是安装系统,部署服务.处理紧急故障,为公司里的开发人员 ...

  6. loadView在App启动时到底都干了些什么?

    loadView在App启动时到底都干了些什么? 查阅苹果官方文档如下: 1. 当你访问一个ViewController的view属性时,如果此时view的值是nil,那么,ViewControlle ...

  7. gcc都做了什么优化

    直接上程序: setjmp和longjmp是处理函数嵌套调用的,goto语句不能跨越函数,所以不选择goto. #include <setjmp.h> int setjmp(jmp_buf ...

  8. Android Intent到底能做些什么

    Android Intent到底能做些什么 原文:http://www.toutiao.com/i6348296465147757058/?tt_from=mobile_qq&utm_camp ...

  9. configure, make, make install都做了什么

    1. 我的理解./configure:  确保接下来的make以及make install所依赖的文件没有问题make:  build编译连接生成可执行程序make install: 将编译好的可执行 ...

随机推荐

  1. 001 01 Android 零基础入门 01 Java基础语法 01 Java初识 01 导学

    001 01 Android 零基础入门 01 Java基础语法 01 Java初识 01 导学 welcome to Java World 欢迎来到Java世界 一起领略Java编程世界的奥秘与奥妙 ...

  2. 【题解】 [EZEC-4]求和

    对于百分之十的数据:随便过. 下面推式子: \[\sum_{i=1}^n\sum_{j=1}^n\gcd(i,j)^{i+j} \] \[=\sum_{d=1}^n\sum_{i=1}^n\sum_{ ...

  3. 【题解】hdu4757 【TJOI2018】异或

    题目链接 题目大意:有一颗树,有点权,每次询问:一条路径\(x->y\)中与\(z\)异或的最大值,或是以\(x\)为根的子树中与\(y\)异或的最大值. 树剖--还是算了. 观察到,子树的\( ...

  4. JavaScript事件对象属性e.target和this的区别

    前言: Event对象代表事件的状态,比如事件在其中发生的元素.键盘按键的状态.鼠标的位置.鼠标按钮的状态. 事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面,这个对象就是事件对象eve ...

  5. NOIP提高组2013 D2T3 【华容道】

    某王  老师给我们考了一场noip2013的真题...心态爆炸! 题目大意: 有一个n*m的棋盘,每个格子上都有一个棋子,有些格子上的棋子能够移动(可移动的棋子是固定的),棋盘中有一个格子是空的,仍何 ...

  6. centos7 安装k8s kubectl 客户端

    1. 配置k8s的kubelet 管理客户端 1 cat <<EOF > /etc/yum.repos.d/kubernetes.repo 2 [kubernetes] 3 name ...

  7. mycat相关配置文件和参数解析

    #vi /usr/local/mycat/conf/schema.xml<!--######################################################### ...

  8. 解决vue、js 下载图片浏览器默认预览而不是下载

    在网页上,如果我们下载的地址对应的是一个jpg文件,txt文件等,点击链接时,浏览器默认的是打开这些文件而不是下载,那么如何才能实现默认下载呢? 后端解决 这就是Content-Disposition ...

  9. centos8平台使用lscpu查看cpu信息

    一,lscpu所属的包: [root@yjweb ~]# whereis lscpu lscpu: /usr/bin/lscpu /usr/share/man/man1/lscpu.1.gz [roo ...

  10. JavaSE学习笔记04方法、数组

    1.方法 java方法是语句的集合,它们在一起执行一个功能 方法是解决一类问题的步骤的有序组合 方法包含于类或对象中 方法在程序中被创建,在其他地方被引用 设计方法的原则:一个方法只完成1个功能,这样 ...