为什么HashMap初始化容量始终是2的指数

为什么HashMap初始化容量始终是2的指数

1.初始化容量规律

​ 最近刷到一个面试题,问HashMap为了保证散列分布,其容量都是2的指数倍,那如果初始化容量为15怎么办?还会是2的指数倍吗?

​ 因此去阅读了一下源码,发现传递初始化容量创建HashMap时,会调用另外一个构造方法,如下:

//带有初始化容量的构造方法
public HashMap(int initialCapacity) {
        this(initialCapacity, DEFAULT_LOAD_FACTOR);
}

//上面的构造方法调用的是下面这个构造方法
public HashMap(int initialCapacity, float loadFactor) {
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal initial capacity: " +
                                               initialCapacity);
        if (initialCapacity > MAXIMUM_CAPACITY)
            initialCapacity = MAXIMUM_CAPACITY;
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal load factor: " +
                                               loadFactor);
        this.loadFactor = loadFactor;
    	//请注意看这个方法,tableSizeFor(initialCapacity)
        this.threshold = tableSizeFor(initialCapacity);
    }

//tableSizeFor方法,会对传过来的初始化容量进行以下计算
static final int tableSizeFor(int cap) {
        int n = cap - 1;
        n |= n >>> 1;
        n |= n >>> 2;
        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;
        return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
    }

​ 可以通过上面的代码得知,我们传进入的初始化容量并不是直接就会被赋到真正的数组容量当中,而是进行了一系列计算得到最终的初始化容量,可以总结为以下规律:

  • 当传入初始化容量N<2的指数倍,最终初始化容量就是离N最近且大的那个数

    ​ 比如传进来15,那么最终的初始化容量就是16

  • 当传入初始化容量N=2的指数倍,最终初始化容量就是N本身

    ​ 比如传进来16,那么最终的初始化容量就是16

2.二进制探究初始化容量规律

​ 对于以上初始化容量的计算机制,在二进制层面进行剖析:

当传入的初始化容量<2的指数倍时
在这里插入图片描述

当传入的初始化容量=2的指数倍时
在这里插入图片描述

当传入的初始化容量=2的指数倍+1时
在这里插入图片描述

3.总结

​ 根据以上信息得知,在给HashMap传入初始化容量N时,底层总是会将N和其右移数的二进制进行或运算,最终总能得出一个全为1的二进制数,然后进行加1,得到2的指数倍的最终容量。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值