<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      HashMap如何計算初始化容量,最大容量是多少

      摘要:結合HashMap源碼,介紹HashMap如何確定初始化容量,其最大容量是多少。

      ??更多關于HashMap的知識點,請戳《HashMap知識點梳理、常見面試題和源碼分析》。

      ??本文基于Java 17進行分析。

      ??什么是HashMap的容量?容量就是HashMap中的數組大小或者桶的數量,是由 capacity 這個參數確定的。初始容量只是哈希表在創建時的容量。

      ??大家都知道HashMap是采用的懶加載機制,也就是說在執行new HashMap()的時候,構造方法并沒有在構造出HashMap實例的同時也把HashMap實例里所需的數組給初始化。那么,什么時候才去初始化里面的數組呢?答案是在第一次用到數組的時候才會去初始化它,就是在向HashMap里面添加元素的時候。而初始化數組時,它的容量是怎么確定的呢?有兩種情況:
      第一種是調無參構造函數初始化實例。此時默認的數組初始化長度就是16,在后續添加元素時,進行數組初始化。

      public HashMap() {
          this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
      }
      

      ??第二種是調用帶數組容量參數的構造函數。

      public HashMap(int initialCapacity) {
          this(initialCapacity, DEFAULT_LOAD_FACTOR);
      }
      

      或者

      
      /**
       * 如果構造函數傳入的值大于該數,則替換成該數。
       * The maximum capacity, used if a higher value is implicitly specified
       * by either of the constructors with arguments.
       * MUST be a power of two <= 1<<30.
       */
      static final int MAXIMUM_CAPACITY = 1 << 30; // ①
          /**
           * The next size value at which to resize (capacity * load factor).
           * 數組擴容的閾值
           * @serial
           */
          // (The javadoc description is true upon serialization.
          // Additionally, if the table array has not been allocated, this
          // field holds the initial array capacity, or zero signifying
          // DEFAULT_INITIAL_CAPACITY.)
          int threshold;
      
      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;
          this.threshold = tableSizeFor(initialCapacity);
      }
      

      ??顯而易見,上面那個構造方法執行的時候調用的就是下一個構造方法 this(initialCapacity, DEFAULT_LOAD_FACTOR)。當你調用帶參構造器初始化一個指定數組容量的HashMap時,構造器會根據輸入的參數提前計算出數組實際的長度,這個值也是在首次添加元素時起作用。計算的邏輯在函數 tableSizeFor(int cap) 中,源碼如下:

      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; // ③ 判斷是否超過最大容量
      }
      

      ??它對入參cap減一之后使用了無符號右移,然后進行或運算,將n-1得到的值轉成2進制之后,從1的最高位開始將低位全部轉化為1,再加1之后就可以得到一個2^n的數。

      HashMap的最大容量是2^30

      ??HashMap的最大容量是多少?容量默認是16,也可以構造時傳入,最大值是1<<30,即2^30,這個在源碼①的注釋中已經明確說明。首先必須理解操作符 <<,它是左移操作符,表示對二進制進行左移。通常情況下,1 << x 等于 2^x

      ??上一節中②和③所標記的代碼表明,如果要存的元素數目大于 MAXIMUM_CAPACITY,HashMap方法還把數組大小capacity強制設置成 MAXIMUM_CAPACITY
      ??綜上所述,HashMap限制數組大小最大值有兩個地方,其一就是初始化時調用tableSizeFor()函數,它會將容量置為 2的冪次,并保證不超過MAXIMUM_CAPACITY。其二就是調用擴容函數resize()進行容量翻倍時。如果容量達到MAXIMUM_CAPACITY時允許再擴容,新數組的容量就是 1 << 31,這會造成整型溢出,故Integer.MAX_VALUE是HashMap的最終容量。

      HashMap的最大擴容閾值是2^31-1

      在擴容函數resize()中有一個強制設置閾值大小的代碼片段:

      if (oldCap >= MAXIMUM_CAPACITY) {
          threshold = Integer.MAX_VALUE;
          return oldTab;
      }
      

      hreshold是HashMap所能容納的最大數據量的Node(鍵值對)個數,threshold = length * Load factor。也就是說,在數組定義好長度之后,負載因子越大,所能容納的鍵值對個數越多。

      ??在這里可以看到,其實 HashMap 擴容閾值threshold的最大值就是Integer.MAX_VALUE=2^31-1;

      刷一道面試題

      ??今天看一個關于HashMap的性能問題:如果HashMap只裝載100個元素,new HashMap(int x)中x的最佳值是多少,為什么?

      ??答案:256。

      ??解析:題意是令加載因子取默認值0.75,此時HashMap的初始容量可以設為100/0.75 = 133.33,向上取整為134。
      無論你的HashMap(int x)中的x設置為多少,HashMap的大小都是2n,而且2n是大于x的第一個數,故大于134的第一個2^n無疑是256。

      結束語

      ??以上就是這篇文章的全部內容了,希望本文對道友的學習或者工作能帶來一定的幫助,如有疑問請留言交流。Wiener在此祝各位生活愉快!工作順利!

      ??人情早晚有用完的時候,如若自己擁有足夠的實力,定能贏得別人的尊重。更何況沒有人欠我們人情呢!為人處世尚且如此,披星戴月的碼農是不是要刻苦鉆研,拓展技術棧的廣度和深度呢?

      Reference

      posted @ 2022-04-16 20:18  樓蘭胡楊  閱讀(2355)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产成人欧美一区二区三区| 精品国产中文字幕在线| 亚成区成线在人线免费99| 国产在线拍偷自揄观看视频网站 | 精品久久久久久亚洲综合网| 久久精品视频一二三四区| 日产国产一区二区不卡| 亚洲三区在线观看内射后入 | 日本丰满少妇裸体自慰| 90后极品粉嫩小泬20p| 中文国产人精品久久蜜桃| 337p西西人体大胆瓣开下部| 国产一区二区三区亚洲精品| 久久精品国产亚洲精品2020| 大同市| 国产三级精品片| 亚洲国产精品自在拍在线播放蜜臀| 午夜高清福利在线观看| 国产精品久久777777| 2020年最新国产精品正在播放| 精品国产免费第一区二区三区| 亚洲精品动漫一区二区三| 粗大挺进朋友人妻淑娟| 亚洲精品毛片一区二区| 中国性欧美videofree精品| 国产在视频线在精品视频2020| 欧洲免费一区二区三区视频| 日韩欧激情一区二区三区| 精品一卡2卡三卡4卡乱码精品视频| 中国亚洲女人69内射少妇| 欧美奶涨边摸边做爰视频| 国产精成人品日日拍夜夜| 中文字幕久久熟女蜜桃 | 婷婷丁香五月深爱憿情网| 欧美人与动牲猛交A欧美精品 | 亚洲精品国偷拍自产在线观看蜜臀| av新版天堂在线观看| 四虎精品永久在线视频| 久久人人爽人人人人爽av| 伊人久久大香线蕉网av| 台湾佬自拍偷区亚洲综合|