1. 程式人生 > >HashMap的長度為什麼設定為2的n次方

HashMap的長度為什麼設定為2的n次方

1. 建構函式中控制長度必須為2的n次方.

首先在構造方法中, 有下面這段程式碼, 其中initialCapacity是我們傳入的自定義map容量大小(如果不設定, 預設是16)
如果我們自定義容量, 會執行下面這段程式碼 :
這裡寫圖片描述
initialCapacity = 8, 這樣capacity = 1, 要向左移動3次, 剛開始移動之前capacity=1, 根據移位運算, 移動第1次, capacity=2, 移動第2次, capacity=4,移動第3次, capacity=8, 此時會跳出迴圈, 最終capacity = 8 = 2的3次方
initialCapacity = 5, 這樣capacity = 1, 要向左移動3次, 剛開始移動之前capacity=1, 根據移位運算, 移動第1次, capacity=2, 移動第2次, capacity=4,移動第3次, capacity=8, 此時會跳出迴圈, 最終capacity = 8 = 2的3次方
所以同理, 如果輸入是5, 6, 7, 8, 最終的capacity=8, 也就是對於某個數A, 找到大於等於A中最小的數B, 並且B=2的n次方 . 因為HashMap中要求Entry陣列的長度是2的n次方, 後面我們會知道這種方式的好處 .
所以在這個地方, 就嚴格控制了長度必須是2的n次方 .

2. 這種方式好處.

上面說了建構函式中, 限制了capacity必須是2的n次方 .
並且在擴容的時候, 也是直接乘以2進行擴容, 保證還是2的n次方 .
這裡寫圖片描述
好處 :
這裡的h是”int hash = hash(key.hashCode());”, 也就是根據key的hashCode再次進行一次hash操作計算出來的 .
length是Entry陣列的長度 .
一般我們利用hash碼, 計算出在一個數組的索引, 常用方式是”h % length”, 也就是求餘的方式 .
可能是這種方式效率不高, SUN大師們發現, “當容量一定是2^n時,h & (length - 1) == h % length” . 按位運算特別快 .
這裡寫圖片描述


對於length = 16, 對應二進位制”1 0000”, length-1=”0 1111”
假設此時h = 17 .
(1) 使用”h % length”, 也就是”17 % 16”, 結果是1 .
(2) 使用”h & (length - 1)”, 也就是 “1 0001 & 0 1111”, 結果也是1 .
我們會發現, 因為”0 1111”低位都是”1”, 進行”&”操作, 就能成功保留”1 0001”對應的低位, 將高位的都丟棄, 低位是多少, 最後結果就是多少 .
剛好低位的範圍是”0~15”, 剛好是長度為length=16的所有索引 .

相關推薦

HashMap長度為什麼設定2的n次方

1. 建構函式中控制長度必須為2的n次方. 首先在構造方法中, 有下面這段程式碼, 其中initialCapacity是我們傳入的自定義map容量大小(如果不設定, 預設是16) 如果我們自

為什麼 HashMap 的容量大小要設定2的N次方

原文連結:https://www.changxuan.top/?p=1208 前兩天,我在一位同學提交中看到了下面這樣的一行程式碼,讓我很是驚訝。 Map<String, String> temp = new HashMap<>(6)

c++ 將容量設定容器的長度(shrink_to_fit)

  #include <iostream> #include <vector> using namespace std; int main () { vector<int> myvector (25); cout << "1.

長度2N的陣列分割成2個長度N的陣列,且兩陣列的和的差的絕對值最小

題目如圖,題意比較簡單,然後用動態規劃進行求解。一開始沒怎麼考慮是負數的問題,然後就有個mus整數表示最小的負數,然後所有的數都加上這個數。。。初步程式碼,有點簡陋,大概能簡單重寫一下。後來發現和 http://blog.csdn.net/tmljs1988/article/details/6712

Android進階UI之ImageView設定長度高度wrap_content時高度根據圖片比例自適應

1 示例 <ImageView android:id="@+id/img_1" android:layout_width="fill_parent" android:layout_height="wrap_cont

為什麼HashMap的初始容量一定要設定16(2的整數次冪)?

HaspMap的資料結構是陣列加單鏈表,把初始容量設定為2的冪有助於HashMap中的元素存放地更均勻,降低了hash碰撞的概率,提高了查詢的效率和空間利用率。 最理想的情況是Entry陣列中每一個位置都只存放一個元素,這樣在查詢的時候不用去遍歷連結串列,這時候空間利用率最大,時間複雜度

如何將 Windows 8 的預設輸入法設定英文

Windows 8 的預設輸入法是中文,需要按一下 SHIFT 才能切換成英文,很不方便。 下面教大家如何將 Windows 8 的預設輸入法設定為英文 1.開啟控制面板,找到“語言”項。 2.點選“新增語言”,找到“英語”選項。 3.點選“開啟”-->選擇“英語(

使用Heroku,需要將locale設定zh_CN,而不是zh-CN

使用Heroku,需要將locale設定為zh_CN,而不是zh-CN 我想大概是因為在application.rb中,config.i18n.default_locale預設接受的值是Symbol, 而當我們用zh-CN的時候,不得不用雙引號括起來, 但是實際Rails讀取的時候,可能直接

【20181101】MySQL text型別的column設定NOT NULL 導致主從1364

環境 系統版本 : CentOS release 6.8 (Final) MySQL版本:5.6.29-log MySQL Community Server (GPL) MySQL主從配置資訊 binlog format :MIXED sql_mode: NO_AUTO_CREATE_USE

將myeclipse預設編碼設定UTF-8

  出處: 【 CSDN 】:csdn.zxiaofan.com Window->Preferences->General ->Content Type->Text->JSP 最下面設定為UTF-8

Requests將verify設定False後取消警告的方式

方法一 1 import requests 2 from requests.packages import urllib3 3 urllib3.disable_warnings() 4 resp = requests.get('https://www.***.com',

如何將自己的exe程式設定開機自啟動

如何將自己的exe程式設定為開機自啟動 將自己的exe程式設定為開機自啟動 話不多說,直接看 首先 1:cmd—>regedit 其次找到下面的路徑就可以:(以win10為例) 計算機\HKEY_CURRENT_USER\Software\Microsoft\Win

函式設定內聯inline之後編譯報錯LINK ERROR 2019相關

   在改程式碼的時候,將一些函式設定為行內函數在debug版本下沒問題,但是編譯成release時報錯,具體錯誤表現如圖: 我查了一下,原因是行內函數宣告與定義分開時,不可以被其他檔案引用。就是說,在類A中,有一個行內函數a(),如果我們在A.h中對其宣告並定義,那麼並

樹莓派 3b jupyter notebook 設定後臺服務

情景說明: 樹莓派上已經搭建好了jupyter,命令jupyter notebook可以啟動,在區域網/外網都可以通過瀏覽器訪問.在終端內執行jupyter notebook會一直佔據命令列. 後臺實現:jupyter notebook > output.file 2&>

MySql建立Table的時候將編碼設定utf-8

設定資料表編碼 CREATE TABLE 'BmapTable' ( ID VARCHAR(64) NOT NULL, NAME VARCHAR(64) NOT NULL, ADDRESS VARCHAR(64), LONGITUDE VARCHAR(

vue框架下,echarts圖表外部容器寬度設定百分比時內容超出容器以及echarts圖表自適應的實現方案

在vue.js框架下,建立echarts圖表,當圖表的外部容器的寬度設定為百分比時,出現圖表內容寬度超出其外部容器的情況,幾番除錯,得解決方案如下: (備註說明:問題產生的具體原因尚不清晰,後面若知曉了再補充,但是初期解決問題階段一定不要鑽牛角,不是一開始就能或者可以知道真理的) 在建立了e

用C程式設計,設定兩個外部中斷(INT0和INT1)按鍵,優先順序IP=0x04,即把外部中斷1設定高階優先順序,外部中斷0低階優先順序,使外部中斷1巢狀在外部中斷0中。

問題 用C程式設計,設定兩個外部中斷(INT0和INT1)按鍵,優先順序IP=0x04,即把外部中斷1設定為高階優先順序,外部中斷0為低階優先順序,使外部中斷1巢狀在外部中斷0中。 要求:中斷觸發方式為下降沿觸發,按鍵有消抖功能 模擬 程式碼 #include <

C/C++網路程式設計在windows和linux中將socket設定阻塞和非阻塞

C/C++網路程式設計在windows和linux中將socket設定為阻塞和非阻塞              在 socket程式設計中,對於socket的讀寫預設都是阻塞的,但有的情況我們需要將其設定為非阻塞,比如做多

IE8中的input設定disabled時,字型顏色設定問題

關於Input不能修改,設定屬性可以為disabled或者readonly 但是,如果設定為disabled,關於字型顏色的設定則不再有效,disabled對顏色的設定免疫,因為顏色太淡,使用者體驗差,所以用readonly,但是readonly會出現游標的閃爍問題,需要設定屬性: $('i

Linux系統如何將Python的預設環境設定anaconda下,檢視tensorFlow版本

我是Ubuntu 16.04的 (可以通過命令sudo lsb_release -a檢視版本) 裡面系統自帶2.7,我裝Anaconda後 裝了tensorFlow3 和python3.6 ① 找到Python3.6資料夾, 我的目錄是:/home/yuyilanubuntu/ana