淺談某些容器底層

剛開始學,稀裏糊塗的寫一點。。。

ArrayList

參考博客:https://www.cnblogs.com/leesf456/p/5308358.html

1、ArrayList底層的數據結構其實就是一個可變數組,數組的元素類型是Object類型,可以存放各種類型的數據,允許null的存在。

2、ArrayList繼承了AbstractList抽象父類,實現了List接口(規定了List的操作規範)、RandomAccess(可隨機訪問)、          Cloneable(可拷貝)、Serializable(可序列化)。

public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable

3、數組默認大小爲10,實際元素個數默認爲0。

4、當實際元素個數達到容量大小時,會進行擴容,擴容後的數組大小大約爲舊數組大小的1.5倍。特殊情況:擴展的新數組大小達到最大值,則只能取最大值。

5、remove函數,會把下標到末尾的元素都向前移動一位,並把最後一個位置置爲null,這樣做是爲了方便GC。

6、採用了Fail-Fast(快速失敗)機制,面對併發的修改時,迭代器很快就會完全失敗。

LinkedList

參考博客:https://www.cnblogs.com/leesf456/p/5308843.html

1、LinkedList底層的數據結構是雙向鏈表,並且有一個頭節點和一個尾節點,這樣既可以從頭正向遍歷,也可以從尾逆向遍歷。允許null的存在。

2、雙向鏈表節點是類Node的實例,包含的成員變量:prev,next,item。prev是該節點的上一個節點,next是該節點的下一個節點,item是該節點的值。

3、get函數和addall函數都會用到node函數,node函數的作用是根據索引下標找到該結點並返回。在node函數裏面有一個小的優化,首先會判斷下標在前半部分還是在後半部分,在前半部分時就正向遍歷,否則逆向遍歷,這樣就保證了最多遍歷n/2個元素,節省了時間。

HashMap

參考博客:東拼西湊的看的。。。

1、HashMap底層是數組+鏈表+紅黑樹(紅黑樹還有待學習)實現的,數組中的每一項都是一個單向鏈表,允許使用null鍵和null值,但不保證映射的順序。

2、數組默認大小是16,加載因子默認大小是0.75,也可以自行設定容量以及加載因子,當放入的鍵值對數量超過容量乘以加載因子(即閾值)的時候,就會進行擴容。

3、當對key進行hash時,如果有hash值相等的,那麼就會形成一個鏈表,如果鏈表的長度超過了8,那麼就會轉化成紅黑樹,不轉化會降低查詢效率。

4、採用了Fail-Fast機制,通過一個modCount值記錄修改次數,對HashMap內容的修改都將增加這個值。迭代器初始化過程中會將這個值賦給迭代器的expectedModCount,在迭代過程中,判斷modCount跟expectedModCount是否相等,如果不相等就表示已經有其他線程修改了Map,馬上拋出異常。

HashTable

參考博客:https://blog.csdn.net/varyall/article/details/80992123

1、採用Fail-Fast機制。

2、HashTable的底層是數組+鏈表實現的,不允許使用null鍵和null值。

3、默認數組容量爲11,加載因子爲0.75,也可以自行設定。

4、與HashMap實現差不多,且沒有紅黑樹的引入。

5、擴容時,新數組的長度爲舊數組長度 * 2 + 1。

Hash Map與Hash Table的區別

1、HashMap可以允許存在一個爲null的key和任意個爲null的value,但是HashTable中的key和value都不允許爲null。

2、Hashtable的方法是同步的,而HashMap的方法不是。所以有人一般都建議如果是涉及到多線程同步時採用HashTable,沒有涉及就採用HashMap。

3、兩個遍歷方式的內部實現上不同。Hashtable、HashMap都使用了 Iterator。而由於歷史原因,Hashtable還使用了Enumeration的方式 。

4、計算hash值的不同。HashTable通過hashCode方法計算得到的hash值,就爲最終的hash值;而HashMap是先通過hashCode方法計算得到一個hash值,然後再將這個hash值與右移16位之後異或,得到最終的hash值。

5、HashTable默認數組長度爲11,擴容後新數組長度 = 舊數組長度 * 2 + 1;HashMap默認數組長度爲16,擴容後新數組長度 = 舊數組長度 * 2。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章