集合各實現類的底層實現原理

2021-10-24 16:54:39 字數 2822 閱讀 5666

arraylist是list介面的可變陣列非同步實現,並允許包括null在內的所有元素。

底層使用陣列實現

該集合是可變長度陣列,陣列擴容時,會將老陣列中的元素重新拷貝乙份到新的陣列中,每次陣列容量增長大約是其容量的1.5倍,這種操作的代價很高。若是能預估到頂峰容量,可以設定乙個足夠大的量以避免陣列容量以後的擴充套件。

採用了fail-fast機制,面對併發的修改時,迭代器很快就會完全失敗,而不是冒著在將來某個不確定時間發生任意不確定行為的風險

remove方法會讓下標到陣列末尾的元素向前移動乙個單位,並把最後一位的值置空,方便gc

add、remove操作對於arraylist其執行時間是o(n),因為在它當中在前端進行新增或移除構造新陣列是o(n)操作;get方法的呼叫為o(1)操作。要是使用乙個增強的for迴圈,對於任意list的執行時間都是o(n),因為迭代器將有效地從一項到下一項推進。

linkedlist是list介面的雙向鍊錶非同步實現,並允許包括null在內的所有元素。

底層的資料結構是基於雙向鍊錶的,該資料結構我們稱為節點

雙向鍊錶節點對應的類node的例項,node中包含成員變數:prev,next,item。其中,prev是該節點的上乙個節點,next是該節點的下乙個節點,item是該節點所包含的值。

它的查詢是分兩半查詢,先判斷index是在鍊錶的哪一半,然後再去對應區域查詢,這樣最多只要遍歷鍊錶的一半節點即可找到

add、remove操作對於linkedlist其執行時間是o(1);get方法的呼叫為o(n)操作。要是使用乙個增強的for迴圈,對於任意list的執行時間都是o(n),因為迭代器將有效地從一項到下一項推進。

hashmap是基於雜湊表的map介面的非同步實現,允許使用null值和null鍵,但不保證對映的順序。

底層使用陣列實現,陣列中每一項是個單向鍊錶,即陣列和鍊錶的結合體;當鍊表長度大於一定閾值時,鍊錶轉換為紅黑樹,這樣減少鍊錶查詢時間。

hashmap在底層將key-value當成乙個整體進行處理,這個整體就是乙個node物件。hashmap底層採用乙個node陣列來儲存所有的key-value對,當需要儲存乙個node物件時,會根據key的hash演算法來決定其在陣列中的儲存位置,在根據equals方法決定其在該陣列位置上的鍊錶中的儲存位置;當需要取出乙個node時,也會根據key的hash演算法找到其在陣列中的儲存位置,再根據equals方法從該位置上的鍊錶中取出該node。

hashmap進行陣列擴容需要重新計算擴容後每個元素在陣列中的位置,很耗效能

採用了fail-fast機制,通過乙個modcount值記錄修改次數,對hashmap內容的修改都將增加這個值。迭代器初始化過程中會將這個值賦給迭代器的expectedmodcount,在迭代過程中,判斷modcount跟expectedmodcount是否相等,如果不相等就表示已經有其他執行緒修改了map,馬上丟擲異常

hashtable是基於雜湊表的map介面的同步實現,不允許使用null值和null鍵

底層使用陣列實現,陣列中每一項是個單鏈表,即陣列和鍊錶的結合體

synchronized是針對整張hash表的,即每次鎖住整張表讓執行緒獨佔

hashtable在底層將key-value當成乙個整體進行處理,這個整體就是乙個entry物件。hashtable底層採用乙個entry陣列來儲存所有的key-value對,當需要儲存乙個entry物件時,會根據key的hash演算法來決定其在陣列中的儲存位置,在根據equals方法決定其在該陣列位置上的鍊錶中的儲存位置;當需要取出乙個entry時,也會根據key的hash演算法找到其在陣列中的儲存位置,再根據equals方法從該位置上的鍊錶中取出該entry。

concurrenthashmap允許多個修改操作併發進行,其關鍵在於使用了鎖分離技術。

與hashmap不同的是,concurrenthashmap使用多個子hash表,也就是段(segment)

它使用了多個鎖來控制對hash表的不同段進行的修改,每個段其實就是乙個小的hashtable,它們有自己的鎖。只要多個併發發生在不同的段上,它們就可以併發進行。

concurrenthashmap完全允許多個讀操作併發進行,讀操作並不需要加鎖。如果使用傳統的技術,如hashmap中的實現,如果允許可以在hash鏈的中間新增或刪除元素,讀操作不加鎖將得到不一致的資料。concurrenthashmap實現技術是保證hashentry幾乎是不可變的。

concurrenthashmap在底層將key-value當成乙個整體進行處理,這個整體就是乙個entry物件。hashtable底層採用乙個entry陣列來儲存所有的key-value對,當需要儲存乙個entry物件時,會根據key的hash演算法來決定其在陣列中的儲存位置,在根據equals方法決定其在該陣列位置上的鍊錶中的儲存位置;當需要取出乙個entry時,也會根據key的hash演算法找到其在陣列中的儲存位置,再根據equals方法從該位置上的鍊錶中取出該entry。

hashset由雜湊表(實際上是乙個hashmap例項)支援,不保證set的迭代順序,並允許使用null元素。

基於hashmap實現,api也是對hashmap的行為進行了封裝,可參考hashmap

linkedhashmap繼承於hashmap,底層使用雜湊表和雙向鍊錶來儲存所有元素,並且它是非同步,允許使用null值和null鍵。

基本操作與父類hashmap相似,通過重寫hashmap相關方法,重新定義了陣列中儲存的元素entry,來實現自己的鏈結列表特性。該entry除了儲存當前物件的引用外,還儲存了其上乙個元素before和下乙個元素after的引用,從而構成了雙向鏈結列表。

對於linkedhashset而言,它繼承與hashset、又基於linkedhashmap來實現的。linkedhashset底層使用linkedhashmap來儲存所有元素,它繼承與hashset,其所有的方法操作上又與hashset相同。

集合各實現類的底層實現原理

參考文獻 arraylist是list介面的可變陣列非同步實現,並允許包括null在內的所有元素。底層使用陣列實現 該集合是可變長度陣列,陣列擴容時,會將老陣列中的元素重新拷貝乙份到新的陣列中,每次陣列容量增長大約是其容量的1.5倍,這種操作的代價很高。採用了fail fast機制,面對併發的修改時...

集合各實現類的底層實現原理

底層使用陣列實現 該集合是可變長度陣列,陣列擴容時,會將老陣列中的元素重新拷貝乙份到新的陣列中,每次陣列容量增長大約是其容量的1.5倍,這種操作的代價很高。預設10 採用了fail fast機制,面對併發的修改時,迭代器很快就會完全失敗,而不是冒著在將來某個不確定時間發生任意不確定行為的風險 rem...

集合各實現類的底層實現原理

參考文獻 arraylist是list介面的可變陣列非同步實現,並允許包括null在內的所有元素。底層使用陣列實現 該集合是可變長度陣列,陣列擴容時,會將老陣列中的元素重新拷貝乙份到新的陣列中,每次陣列容量增長大約是其容量的1.5倍,這種操作的代價很高。採用了fail fast機制,面對併發的修改時...