HashMap的最大容量為什麼是2的30次方(1左移30)?
引言
在閱讀hashmap的原始碼過程中,我看到了關於hashmap最大容量的限制,併產生了一絲疑問。
/**
* 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;
為啥最大容量是 1 << 30?
探究過程1 – 為什麼是30
首先是 <<
這個操作符必須要理解,在一般情況下 1 << x
等於 2^x
。這是左移操作符,對二進位制進行左移。
來看1 << 30。它代表將1左移30位,也就是0010...0
來看這樣一段程式碼:
public static void main(String[] args){
for (int i = 30; i <= 33; i++) {
System.out.println("1 << "+ i +" = "+(1 << i));
}
System.out.println("1 << -1 = " + (1 << -1));
}
輸出結果為:
1 << 30 = 1073741824
1 << 31 = -2147483648
1 << 32 = 1
1 << 33 = 2
1 << -1 = -2147483648
結果分析:
- int型別是32位整型,佔4個位元組。
- Java的原始型別裡沒有無符號型別。 -->所以首位是符號位 正數為0,負數為1
- java中存放的是補碼,1左移31位的為 16進位制的
0x80000000
代表的是-2147483648–>所以最大隻能是30
探究過程2 – 為什麼是 1 << 30
探究完1相信大家對 為什麼是30有一點點了解。那為什麼是 1 << 30,而不是0x7ffffff
即Integer.MAX_VALUE
我們首先看程式碼的註釋
/**
* 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;
翻譯一下大概就是:如果建構函式傳入的值大於該數 ,那麼替換成該數。
ok,我們看看建構函式的呼叫:
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);
}
其中這一句:
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
看到這有很有疑問了,如果我要存的數目大於 MAXIMUM_CAPACITY,你還把我的容量縮小成 MAXIMUM_CAPACITY???
別急繼續看:在resize()方法中有一句:
if (oldCap >= MAXIMUM_CAPACITY) {
threshold = Integer.MAX_VALUE;
return oldTab;
}
在這裡我們可以看到其實 hashmap的“最大容量“是Integer.MAX_VALUE;
總結
MAXIMUM_CAPACITY作為一個2的冪方中最大值,這個值的作用涉及的比較廣。其中有一點比較重要的是在hashmap中容量會確保是 2的k次方,即使你傳入的初始容量不是 2的k次方,tableSizeFor()方法也會將你的容量置為 2的k次方。這時候MAX_VALUE就代表了最大的容量值。
另外還有一點就是threshold,如果對hashmap有一點了解的人都會知道threshold = 初始容量 * 載入因子。也就是擴容的 門檻。相當於實際使用的容量。而擴容都是翻倍的擴容。那麼當容量到達MAXIMUM_CAPACITY,這時候再擴容就是 1 << 31 整型溢位。所以Integer.MAX_VALUE作為最終的容量,但是是一個threshold的身份。
相關文章
- 為什麼 HashMap 的容量大小要設定為2的N次方?HashMap
- hashMap 的size 為什麼 是2的 n次方倍HashMap
- HashMap的table長度為什麼是2的n次HashMap
- 30 分鐘理解 CORB 是什麼ORB
- bose qc30 安靜的城市是什麼樣子
- 我為什麼不要30歲以上的程式設計師?程式設計師
- 什麼是DevSecOps?開發人員如何為安全而左移dev
- 4個月損失30%玩家,你為什麼不玩DOTA2了?
- 我是這樣成為年薪30萬的前端!前端
- 華為P30與華為P30 Pro拍照評測:華為P30/P30 Pro拍照怎麼樣?
- 29-HashMap 為什麼是執行緒不安全的?HashMap執行緒
- 0的階乘為什麼是1
- 什麼是測試左移和測試右移
- 30歲後,你還剩下什麼?
- 面試官問:為什麼HashMap底層樹化的元素是 8面試HashMap
- 1、為什麼軟體開發週期總是預估的2~3倍? 2、什麼是分而治之? 3、瞭解WBS
- 常用的HashMap到底是個什麼結構HashMap
- 保姆級教程!2 萬字 + 30 張圖搞懂 MySQL 是怎麼加行級鎖的?MySql
- 【資料結構】30、hashmap=》hash 計算方式資料結構HashMap
- jmeter 壓測結果平均時間是 30 多秒,但是我在壓測期間頁面操作又很快(1-2)秒這是為什麼呢?JMeter
- 為什麼HashMap的鍵值可以為null,而ConcurrentHashMap不行?HashMapNull
- 雲容量是怎麼管理的
- 初學者為什麼要學Python?python的30個操作難點總結!Python
- 原始碼分析為什麼HashMap的table長度一定是2的整次冪原始碼HashMap
- 一元1次方一元2次方的通道
- ">/dev/null 2>&1 "是什麼意思devNull
- 什麼是前奏設計 1/2
- 如何用 30s 給面試官講清楚什麼是 Token面試
- day30-JavaScript(2)JavaScript
- 次世代主機:為什麼我們還將繼續玩30幀的遊戲遊戲
- 30k的照片jpg畫素是多大尺寸 30k的照片水平垂直畫素怎麼設定裁剪
- 30歲轉行做初級程式設計師是一種什麼樣的體驗?程式設計師
- 30 歲了,還不知道想做什麼
- 爆肝30小時後,我想告訴你《原神》是什麼
- 為什麼不建議使用自定義Object作為HashMap的key?ObjectHashMap
- 推行精益生產的最大阻力是什麼
- 阿里失敗的最大原因是什麼?阿里
- Parasoft軟體測試實踐:什麼是左移測試?