【问题标题】:HashMap resizing its tableHashMap 调整其表的大小
【发布时间】:2017-09-06 10:44:14
【问题描述】:

我知道 HashMap 的大小默认为 16,我们还可以为其提供一些其他值。如果我将大小初始化为 5,负载因子为 0.8f,然后我将第五个元素添加到它。它会增长到 10 还是 16?一旦阈值突破发生在非 2 的幂值上,它会跳到 2 的幂吗?

【问题讨论】:

    标签: java hashmap


    【解决方案1】:

    最好看看source code

     final Node<K,V>[]  [More ...] resize() {      
             Node<K,V>[] oldTab = table;  
             int oldCap = (oldTab == null) ? 0 : oldTab.length;
             int oldThr = threshold;
             int newCap, newThr = 0;   
             if (oldCap > 0) {   
                 if (oldCap >= MAXIMUM_CAPACITY) {   
                     threshold = Integer.MAX_VALUE;   
                     return oldTab;    
                 }    
                 else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&   
                          oldCap >= DEFAULT_INITIAL_CAPACITY)    
                     newThr = oldThr << 1; // double threshold    
             }    
             else if (oldThr > 0) // initial capacity was placed in threshold    
                 newCap = oldThr;
             ...
             // The capacity of the inner data structure is doubled
             Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];
             table = newTab;
             ...
    

    因此,当前容量和阈值在调整大小时翻倍。

    然而,构造一个初始容量不是2的幂的HashMap对象是不可能的!构造函数将初始容量转换为 2 的幂:

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

    【讨论】:

    • @ZerekSees 很高兴为您提供帮助!
    • 我想知道为什么初始容量必须是 2 的幂?它会是通过容量的最接近的高数吗?
    • @voipp 因为更容易实现。使用 2 的幂,您可以轻松地对位使用位移和其他操作,参见例如这个答案:stackoverflow.com/questions/8352378/…
    猜你喜欢
    • 1970-01-01
    • 2020-12-09
    • 1970-01-01
    • 2016-01-14
    • 2012-09-23
    • 2012-12-24
    • 2016-06-18
    • 1970-01-01
    • 2011-05-03
    相关资源
    最近更新 更多