關於HashMap的一些疑問與解答

2022-09-09 11:06:26 字數 1665 閱讀 7886

1.為什麼treeify_threshold要是8?

treefy是有成本的,新增或刪除元素時有額外的操作,同時treenode是普通node體積的二倍,因而需要乙個平衡點。

隨機hashcode下符合泊松分布,

* 0: 0.60653066

* 1: 0.30326533

* 2: 0.07581633

* 3: 0.01263606

* 4: 0.00157952

* 5: 0.00015795

* 6: 0.00001316

* 7: 0.00000094

* 8: 0.00000006

乙個桶內8個元素的概率為一億分之六;

當情況發生時,說明hashcode設計的不合理,此時會有大量碰撞,這種情況下維護樹就是有必要的。

這個值越小,樹化的影響就越強力,當小於8時,就可能導致頻繁的樹化,增加維護成本。

普通node內部維護的屬性有:

int hash,

k key,

v val,

nodenext

treenode維護的屬性有:

int hash,

k key,

v val,

nodenext

以及treenodeparent;

treenodeleft;

treenoderight;

treenodeprev;

大約是普通node大小的2倍

2.為什麼put方法中的hash值要再進行一次加工,為何要使用 ( h = k.hashcode() ) ^ ( h >>> 16 ) 操作?

計算桶位置的方法為 (tab.length - 1) & hash

一般來說,hashmap的長度不會過大,不會超過65536(1 << 16),只有hash的低16(左右)位參與計算,如果直接將 k.hashcode() 當作hash進行位置計算的話,

則其中的高16(左右)位資訊並未參與計算,而 ( h = k.hashcode() ) ^ ( h >>> 16 ) 演算法將高16位中的資訊加以利用,得出低16位更加隨機的hash,

從而使桶的分布更佳均勻,使用^運算而不是&或者|,是因為^不會使結果有概率上的偏向性。

tab.length固定為2的次方,二進位制即為最高位有效位為1,

其餘位均為0的數字,tab.length - 1即為所有有效位均為1的二進位制數字.

hash對其求&,則獲得的值x >= 0 且x <= tab.length - 1,共 tab.length 個,且分布完全依賴於hash的與tab.length - 1位數相同的低位。

3.擴容時擴大多少,為什麼?

容量擴大為原來的二倍( oldcap << 1 ),該方法配合尋桶演算法 hash & (newcap - 1) 使用,

使得擴容後元素在新陣列中分布均勻(newcap - 1二進位制最高有效位對應的hash相應的位如果為1,則桶位置下標為(原來的下表 + oldcap),若為0,則桶位置不變,

0,1是依賴於hashcode的,隨機的,所以理論上是均勻的)

關於hashmap的一些操作

兩個hashmap比對值然後把相同的值儲存到list裡 for entryentry map.entryset public static mapdothing mapmap else return map3 public static void removenullvalue map map pr...

關於LINUX驅動的一些疑問

1,像字元裝置混雜裝置,都只註冊乙個裝置就ok了,為了什麼都的驅動除了註冊裝置還要註冊驅動。而驅動結構體裡面一般都有probe函式。2.平台分驅動註冊和裝置註冊這個我是知道的,註冊完了會呼叫驅動結構體裡面的probe函式,好像真正的驅動都是在裝置結構體裡面完成了,話有裝置 節點的生成。3,除了這些,...

關於WiMax認證的一些疑問

使用x supplicant和openssl來實現eap tls的認證方式。在認證完成之前,並沒有獲得ip,那麼eap tls如何實現的呢?沒有ip就可以通訊?x supplicant呼叫openssl來幹什麼?只是呼叫openssl的x.509函式來對radius伺服器的證書進行驗證嗎?李春平說 ...