1. 程式人生 > >為什麼HashMap的桶數量是2的冪次方

為什麼HashMap的桶數量是2的冪次方

前段時間去面試的時候坐在等候室裡,聽到隔壁會議室裡的面試:

面試官:“你說一下為什麼HashMap的長度為什麼要設計成2的冪次方”

面試者:“因為計算機計算是二進位制運算,所以balabala.....”

當時聽的很模糊,也不知道面試者回答的是不是對的,所以一直記著回來一定要上網查一下正確的原因……

查閱了相關文章後,其實面試者回答的方向是對的,確實是為了提高運算效率。

我們都知道HashMap計算key的位置演算法為:key.hash%length;

檢視原始碼發現實現已優化為:hash & (length - 1),很顯然,因為計算機位運算的效率比直接進行取餘來的快;

可以思考一下什麼當length的值為什麼的時候 hash % length == hash & (length - 1)

答案就是當length為2的冪次方時。

可以驗證一下:5 % 8 = 5,5 & (8 -1) = 110 & 111 = 110 = 5(十進位制)

由此與運算可以思考一下為什麼2的冪次方可以減少Hash碰撞;

因為(2的n次方-1)的二進位制是n個1,一個key的hash值&1111……,就可以保證結果最大程度取決於key.hash。

如果是key.hash & 2n次方,就是 hash % 100……,與運算則後面的結果全都為0,增大了hash碰撞的概率。

相關推薦

為什麼HashMap數量2次方

前段時間去面試的時候坐在等候室裡,聽到隔壁會議室裡的面試: 面試官:“你說一下為什麼HashMap的長度為什麼要設計成2的冪次方” 面試者:“因為計算機計算是二進位制運算,所以balabala.....” 當時聽的很模糊,也不知道面試者回答的是不是對的,所以一直記著回來

HashMap如何處理自定義大小為非2次方

先上原始碼: static final int tableSizeFor(int i) {//i為自定義容器的大小 int j = i - 1; j |= j >>> 1; j

遞歸--練習9--noi8758 2次方表示

efi fine -a ret problem 來源 n! cnblogs color 遞歸--練習9--noi8758 2的冪次方表示 一、心得 找準子問題就好 二、題目 8758:2的冪次方表示 總時間限制: 1000ms 內存限制: 65536kB描述 任何一個

BZOJ 1677 [Usaco2005 Jan]Sumsets 求和:dp 無限背包 / 遞推【2次方之和】

zoj mem iostream memset bzoj -1 target ont 背包 題目鏈接:http://www.lydsy.com/JudgeOnline/problem.php?id=1677 題意:   給定n(n <= 10^6),將n分解為2的冪次

004:2次方表示

nbsp fir 同時 但是 const tor ace fin div 描述 任何一個正整數都可以用2的冪次方表示。例如: 137=27+23+20 同時約定方次用括號來表示,即ab可表示為a(b)。由此可知,137可表示為: 2(7)+2(3)+2(0)

2次方

題目描述 任何一個正整數都可以用2的冪次方表示。例如:137=2^7+2^3+2^0。同時約定方次用括號來表示,即a^b可表示為a(b)。由此可知,137可表示為:2(7)+2(3)+2(0)。 進一步:7=2^2+2+2^0(21用2表示),3=2+2^0 所以最後137可表示為:2(

2的n次,判斷一個數是否能寫成m個2相乘,LeetCode 231號問題 給定一個整數,編寫一個函式來判斷它是否是 2次方

2的n次冪,判斷一個數是否能寫成m個2相乘,LeetCode 231號問題 給定一個整數,編寫一個函式來判斷它是否是 2 的冪次方。 示例 1: 輸入: 1 輸出: true 解釋: 20 = 1 示例 2: 輸入: 16 輸出: true 解釋: 24 = 16 示例 3:

面試:快速判斷一個數是否是2次方,若是,並判斷出來是多少次方

/********************************************************************** 將2的冪次方寫成二進位制形式後,很容易就會發現有一個特點: 二進位制中只有一個1,並且1後面跟了n個0; 因此問題可以轉化為判斷1後

CCF NOI1074. 2次方表示【遞迴】

時間限制: 1000 ms  空間限制: 262144 KB  具體限制   題目描述 任何一個正整數都可以用2的冪次方表示。 例如:137=27+23+20。 同時約定方次用括號來表示,即ab可表示為a(b)。 由此可知,137可表示為:2(7)+2(3)+2(0

HashMap 容量為2的原因

我們都知道 hashmap 的底層是一個數組加連結串列的結構,當向其中新增一個元素的時候,需要根據key的hash值,去確定其在陣列中的具體位置。 看原始碼,我們可以發現,確定陣列位置的實現是 i=(n-1)& hash,其中 n 代表陣列的長度,即map的容量。 當n為2的冪

# 從鍵盤輸入一個正整數,用2次方的形式輸出。約定次方用括號來表示,即表示為2(b),b=1時,省略。例如139=2^7+2^3+2^1+2^0,即:2(7)+2(3)+2+2(0)

樣例輸入: 402 樣例輸出: 2(8)+2(7)+2(4)+2 要求:冪不能重複,如:139=26+26+23+21+20(出現了2個6次方) 參考 C 程式碼: #include<stdio.h> #include<stdlib.h>

【JS】判斷是不是2次方

給定一個整數,編寫一個函式來判斷它是否是 2 的冪次方。 示例 1: 輸入: 1 輸出: true 解釋: 20 = 1 示例 2: 輸入: 16 輸出: true 解釋: 24 = 16 示例 3: 輸入: 218 輸出: false var isPowerOf

CCF NOI1074. 2次方表示 (C++)

1074. 2的冪次方表示 題目描述 任何一個正整數都可以用2的冪次方表示。 例如:137=27+23+20。同時約定方次用括號來表示,即ab可表示為a(b)。由此可知,137可表示為:2(7)+2(3)+2(0)。進一步:7=22+2+20(21用2表示),3=2+20 。

任何一個數都可以用2次方表示

思路:列舉,遞迴 , #include<iostream> #include<cstdio> using namespace std; void try1(int n,int r){ if(n==1) printf("2(%d)",r); else {

如何判斷一個數是否為2次方

最近在OJ上做題,遇到一道題,其中一個細節就是需要判斷一個數是否為2的冪次方。初看似乎很簡單,可我想來想去,竟然無甚好辦法。最後我用一個笨辦法解決了,那就是將2 4 8 16 32… …存到一個數組裡,遍歷一遍陣列就知道了。但是這個辦法著實不優美。 下面介紹一個好辦法  

leetcode——用位運算來做2次方和位元位計數問題

231.給定一個整數,編寫一個函式來判斷它是否是 2 的冪次方。 示例 1: 輸入: 1 輸出: true 解釋: 20 = 1 示例 2: 輸入: 16 輸出: true 解釋: 24 = 16 示例 3: 輸入: 218 輸出: false 思路: 可以用mod去

1208:2次方表示

一、題目描述 任何一個正整數都可以用2的冪次方表示。例如: 137=27+23+20 同時約定方次用括號來表示,即ab可表示為a(b)。由此可知,137可表示為: 2(7)+2(3)+2(0) 進一步:7=22+2+20(21用2表示) 3=2+20 所以最後137可表示為: 2(2(2)+

移位實現除法(除數不是2次方

#include <stdio.h> #include <stdlib.h> int Division(int y,int x) { int sum=0; int i=0; while(y>x)//向左移位直到x>=y {

九度OJ 1095 2次方

題目描述:     Every positive number can be presented by the exponential form.For example, 137 = 2^7 + 2

【程式設計筆記】整數拆分成2次方的和

一個整數總可以拆分為2的冪的和,例如: 7=1+2+4 7=1+2+2+2 7=1+1+1+4 7=1+1+1+2+2 7=1+1+1+1+1+2 7=1+1+1+1+1+1+1 總共有六種不同的拆分方式。 再比如:4可以拆分成:4 = 4,4 = 1 + 1 + 1 + 1,4 = 2 + 2,4=1+1+