zoukankan      html  css  js  c++  java
  • HashMap中 工具方法tableSizeFor的作用

    【转】 https://blog.csdn.net/fan2012huan/article/details/51097331

    首先看下该方法的定义以及被使用的地方

    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;
    }
    
    public HashMap(int initialCapacity, float loadFactor) {
            // code...
            this.threshold = tableSizeFor(initialCapacity);
        }
    

    tableSizeFor()这个方法的作用是找到大于等于给定容量的最小2的次幂值
    >>>这个符号在java里是无符号右移的意思。
    接下来分析一下这个方法的作用。
    第一句

    int n = cap - 1;
    

    先不用考虑,我们分析完后面的之后再回过头来看它
    然后是第二句

    n |= n >>> 1;
    

    我们这里假设n的初始值为9,那么9的二进制表示是
    00000000 00000000 00000000 00001001
    那么经历一次右移之后,二进制表示是
    00000000 00000000 00000000 00000100
    这两个值进行或运算之后,就是
    00000000 00000000 00000000 00001101
    这里我们如果看最高的1的话,那么可以发现右移1位并且或运算之后,使得最高位的右边一位也是1.
    同理,我们可以下一句右移2位并且进行或运算之后,使得最高两位1的后两位也是1.
    我们之后运行到最后一个右移,可以发现n的值变为了
    00000000 00000000 00000000 00001111
    当然该值大于1并且小于最大值那么+1之后,该值就变成了
    00000000 00000000 00000000 00010000
    惊讶的发现这个值不就是2的次幂嘛!!!

    此时我们回到第一句-1,如果给定的n已经是2的次幂,但是不进行-1操作的话,那么得到的值就是大于给定值的最小2的次幂值。
    至于为什么右移到16位,可以得到的最大值是32个1
    11111111 11111111 11111111 11111111
    这个是因为java的int类型用4个字节32位来进行存储的。最往后没有意义。

  • 相关阅读:
    算法之路 level 01 problem set
    算法原理与实践(链表)
    散列表(HashTable)
    系统设计与实践(实战演练)
    桶排序 + 基数排序
    算法原理与实践(二叉树)
    Total Difference String
    【翻译】std::list::remove
    【翻译】std::remove
    Observer模式实践
  • 原文地址:https://www.cnblogs.com/theone67/p/11093243.html
Copyright © 2011-2022 走看看