HashMap插入資料執行流程分析

2021-10-08 08:33:32 字數 2584 閱讀 7505

jdk1.7中的hashmap底層實現為陣列+鍊錶,jdk1.7中的hashmap存在問題:多執行緒狀態下內部陣列擴容時有可能會導致死迴圈。所以,jdk1.8中對hashmap進行了重新實現,其底層實現為陣列+鍊錶+紅黑樹。提高了hashmap的效能。

內部屬性

儲存資料的執行流程

儲存資料原始碼分析

map儲存資料需要呼叫put方法,下面將從put方法切入

public v put

(k key, v value)

put方法內部會呼叫putval方法,以下是putval執行流程

/**

* hash: 待存入資料的key值的hash值

* key: 待存入資料的key值

* value: 待存入資料的value值

* onlyifabsent: 如果key值相等,是否覆蓋原有值

* evict: 陣列處於建立狀態標識

* v:返回值為當前key值的舊值,如果不存在就返回null

**/final v putval

(int hash, k key, v value,

boolean onlyifabsent,

boolean evict)

if(e.hash == hash &&

((k = e.key)

== key ||

(key != null && key.

equals

(k))))

break

; p = e;}}

//e不為空說明存在key值相同的元素,返回舊值

if(e != null)

}++modcount;

//根據整個map中鍵值對的個數,判斷當前陣列是否需要擴容

//size>threshold則需要擴容if(

++size > threshold)

resize()

;afternodeinsertion

(evict)

;return null;

}

以下是hashmap中陣列擴容的流程:

//內部陣列擴容方法

final node

resize()

//如果擴容後容量依然在最大限制範圍內,並且擴容前容量大於預設初始化容量,設定新的閾值為舊閾值的2倍

elseif(

(newcap = oldcap <<1)

< maximum_capacity &&

oldcap >= default_initial_capacity)

newthr = oldthr <<1;

// double threshold

}//陣列容量為0,但是閾值存在,則將閾值設定為擴容目標大小

else

if(oldthr >0)

// initial capacity was placed in threshold

newcap = oldthr;

//按照預設大小初始化陣列

else

if(newthr ==0)

threshold = newthr;

@suppresswarnings()

//按照新的陣列容量大小,建立新的陣列newtab

node

newtab =

(node

)new

node

[newcap]

; table = newtab;

//如果擴容前陣列為null,說明是第一次懶載入初始化陣列,直接返回建立好的newtab即可。

//否則則為陣列擴容

if(oldtab != null)

while迴圈遍歷鍊錶中的每乙個元素,根據(e.hash&oldcap)是否為0將鍊錶拆分為2個鍊錶

doelse

}while

((e = next)

!= null)

;//將lohead為頭結點的鍊錶放在新錶中和擴容前下標相同的位置

if(lotail != null)

//將hihead為頭結點的鍊錶放在[新錶中和擴容前下標+擴容前陣列長度]的位置

if(hitail != null)}}

}}return newtab;

}

另外比較有意思的乙個點是hashmap內部為了保證陣列容量為2的冪次方數,會在tablesizefor方法對外部傳入的陣列容量進行處理,使不論外部傳的值是多少,總能得到乙個2的冪次方數。

方法思路:主要利用的乙個點就是任何乙個2的冪次方數,其二進位制的值只有乙個二進位制位為1,其餘二進位制位都為0。

static

final

inttablesizefor

(int cap)

總結

通過對hashmap原始碼的學習可知:

MapReduce的資料流程 執行流程

由可以看到mapreduce執行下來主要包含這樣幾個步驟 1.首先對輸入資料來源進行切片 2.master排程worker執行map任務 3.worker讀取輸入源片段 4.worker執行map任務,將任務輸出儲存在本地 5.master排程worker執行reduce任務,reduce work...

HashMap元素插入和擴容

從jdk1.8開始hashmap的儲存結構變成了陣列 鍊錶 紅黑樹,單鏈表中元素個數超過指定閾值,會轉化為紅黑樹結構儲存 提高查詢效率 從1.7到1.8,在hash衝突的時候,鍊錶的插入將頭插法改為尾插法,防止在高併發的情緒出現迴圈鍊錶 hashmap的預設陣列大小為16,代表hash陣列的長度 預...

hdmi插入流程

50ms定時器,一直在迴圈輪訓。當5v檢測插入後,判斷在當前訊號源後 rx.open fg會被設定為1 繼續往下走,檢測不到不往下走 void hdmirx timer handler unsigned long arg rx.open fg 1 的情況下走hdmirx hw monitor rx....