HashMap源码之构造函数

构造函数

从构造函数开始说起

public HashMap(int initialCapacity, float loadFactor) {
        //如果指定的初始容量小于0
        if (initialCapacity < 0)
            //非法参数异常
            throw new IllegalArgumentException("Illegal initial capacity: " +
                                               initialCapacity);
        //如果大于初始容量 默认为最大初始容量
        if (initialCapacity > MAXIMUM_CAPACITY)
            initialCapacity = MAXIMUM_CAPACITY;
            //如果装填因子小于0 或者 不是一个数
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal load factor: " +
                                               loadFactor);
        //赋值
        this.loadFactor = loadFactor;
        this.threshold = tableSizeFor(initialCapacity);
    }

threshold是什么??

threshold 要调整大小的下一个大小值(容量*加载因子)。 来自官方API的解释

要调整的下一个 下一个的意思 是 返回2的n次幂表示的数 如果cap为10 则 结果为16

以下是tableSizeFor的源码

/**
     * Returns a power of two size for the given target capacity.
     * 返回扩容后的长度 默认是最接近cap的向上取整 2的n次幂表示的数 如果cap为10 则 结果为16
     */
    //这个函数的作用是 返回 下一个2的n次幂表示的数
    //2的n次幂是怎么表示的  2  4  8  16
    //他们都可以表示为  1+1  3+1  7+1  15+1
    //注意这些奇数的二进制都可以表示为 1 11 111 1111
    //那么以下代码就好理解了 就是 逐步将cap变为 下一个 全是1的二进制数 
    //换句话说整个代码 就是消灭 n中的0 使其变为1

    //  cap=10  n=9
    static final int tableSizeFor(int cap) {
        int n = cap - 1;
        //|= 优先级是最低的 
        //
        n |= n >>> 1;
        //先计算n右移一位再或运算 n |= 9>>>1
        // 0000 1001 
        // 0000 0100
        // 0000 1101
        ;
        // 0000 1101
        // 0000 0011
        // 0000 1111 
      

        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;

        return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
    }

总结 对于 任何 正数n的二进制表达式
n|= n >>> 1
必定使一个相邻的10 变为11 那么再下一次的运算只需
n |= n >>> 2 因为n的二进制中至少会有两个连续的11
理想情况下 这将至少产生 四个连续的1111
所以下次 只需右移动4位

可以对二进制 1000 0000 进行上述位运算 一切就明白了

什么是装填因子

装填因子(load factor)
装填因子(load factor)决定何时对散列表进行再散列
如果装填因子默认为0.75 并且表中超过75%的位置已经填入元素
也就是说 如果表的长度是16当添加第16*0.75+1个元素时 也就是表中元素的个数到达临界值时 表将会进行resize()操作 这个表就会用双倍额的桶数自动地再进行散列
这里的双倍是自动转换为下一个二次幂函数的数

发布了8 篇原创文章 · 获赞 0 · 访问量 208

猜你喜欢

转载自blog.csdn.net/qq_40184765/article/details/104240599