HashMap 源码之 tableSizeFor方法(优快云的第一篇博客)

本文深入解析了HashMap中tableSizeFor方法的工作原理,通过代码分析和位运算符的介绍,详细解释了如何计算传入数值的最小二次幂,适用于Java开发者理解HashMap内部实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码浏览

话不多说 show me the code

    /**
     * Returns a power of two size for the given target capacity.
     * 这个代码的作用是返回传入数的最小二次幂
     */
    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;
    }

看到这个源码的适合我内心是很抗拒的 ,但是也觉的很有意思这个代码,有一种代码之美
精简,整齐 对强迫症玩家及其友好,所以让我们来‘解刨一下’这段代码。

代码分析

首先呢,这段代码的第一行不用多说,只是对入参的int -1 。
但是在下面的多行频繁的用到了>>>|= 这两个运算符 最后一行是一个 ? :的三目运算符

位运算符介绍

运算符操作实例介绍
<<左移2<<2 =8 即 10->1000所有位向左移低位补0
>>右移3>>1=1 即 3/2 =1 11->01所有位向右移 正数补0 负数补1
>>>无符号右移3>>1=1 -3>>>1=2147483646所有位向右移首位补0
&与运算6&3=2两位与运算一方有0则为0 ,1&0=0
I或运算6I3=7两位与运算一方有1则为1 , 1I0=1
^异或6^3=5110^10 =100 相同为0, 不相同为 1
~反码~6=-7全部位取反

示例演示

public static void main(String[] args) {
        System.out.println(tableSizeFor(200010));
        System.out.println(tableSizeFor(100));
        System.out.println(tableSizeFor(65));
        System.out.println(tableSizeFor(20));
    }
// 结果  
// 262144
// 128
// 128
// 32

结果分析

结果就是输入数字的最小2的幂 就65来分析

static final int tableSizeFor(int cap) {
		// cap = 65 = 1000001
        int n = cap - 1; // n=1000000
        n |= n >>> 1; // n = n|(n>>>1) = n|0100000 = 1000000|0100000= 1100000
        n |= n >>> 2;// n = n|(n>>>2) = 1100000|0011000 = 1111000
        n |= n >>> 4;// n = n|(n>>>4) = 1111000|0000111 = 1111111
        n |= n >>> 8;// n = n|(n>>>8) = 1111111|0000000 = 1111111
        n |= n >>> 16;// n = n|(n>>>16) 与上面同无变化 =1111111
        return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
        // MAXIMUM_CAPACITY = 2^30  最后一句先判定后半部分 n>=MAXIMUM_CAPACITY 为 false 所以返回 n+1 = 10000000  n<0 为false 所以返回 n+1 
        //最终结果返回了 10000000 也就是 128
    }

总结

在判定这些看似复杂的运算时 先弄清楚符号的含义 再进行数据的测试 对结果进行分析,相信你会更上一层楼,各位有觉的帮助到你的可以支持下,有哪里出错了也尽管指出,希望和大家共同进步。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值