Java集合容器總結—Collection,Map

Java集合

在這裏插入圖片描述
Collection是集合List,Set,Queue最基本的接口;
Map是映射表最基本的接口;
瞭解如下基本數據結構
1.數組:增刪慢,支持隨機查找;
2.鏈表:增刪快,不支持隨機查找,只能順序訪問;
3.哈希表:查詢速度快,在拉鍊法種查詢速度取決於鏈表長度,無序;
4.隊列:可以兩端出入,可以用鏈表和數組實現;
有序無序是指插入順序:先插在前,後插在後;

一.List

1.ArrayList

1.底層是數組;
2.是有序的,可重複;
3.線程不安全;
4.擴容1.5倍;

2.Vector

1.底層是數組;
2.有序,可重複;
3.線程安全,因爲支持線程同步,訪問速度就下來了;
4.擴容2倍;

3.LinkedList

1.底層是雙向鏈表:可以當作隊列,雙向隊列,堆,棧使用;
2.有序,可重複;
3.線程不安全;

二.Set

1.HashSet

1.底層是哈希表;key值通過hashCode()方法得到hash值,也就是數組下標,如果hash值相同,再通過equals方法比較兩個對象是否相同,相同則覆蓋,不同則放入鏈表中;
2.無序,不可重複;
3.存取速度快;
注:哈希相同就會產生哈希衝突,兩種方法:哈希值下移,和拉鍊法(HashMap的時候會介紹);

2.TreeSet

1.底層是二叉樹;
2.有序,不可重複;
3.按照指定的順序排序,Integer和String可以按默認的TreeSet順序排序,對於自定義的類必須實現Comparable接口,並重寫compare()函數;
4.底層實現是TreeMap;

3.LinkedHashSet

1.無序;
2.繼承HashSet,方法操作同HashSet,底層是LinkedHashMap實現;

三.Map

1.HashMap

1.無序,鍵值不可重複,值可重複;
2.底層哈希表;
3.線程不安全;
4.允許鍵值爲null,擴容2倍;
5.實現結構:

  1. 數組+鏈表——Entry[] table;Entry是鏈表,存儲有:key值,hash值,value和next;
    原理很簡單: key值通過hashCode()方法得到hash值,也就是數組下標,如果hash值相同,再通過equals方法比較兩個對象是否相同,相同則覆蓋,不同則放入鏈表中;放入鏈表的時候 是插在頭部而不是尾部;
    在這裏插入圖片描述
  2. 四個參數在這裏插入圖片描述
    爲甚麼capacity必須保證2的n次方?
    得到數組下標需要hash%capacity,我們比較兩端代碼
    hash%capacity
    hash%(capacity-1)可以發現,當capacity爲2的n次方時,此操作和取模一摸一樣;但在計算計算機中位運算的速度更快;所以採用下面的與運算;
  3. java8實現——數組+鏈表+紅黑樹
    查詢速度取決於鏈表長度,當鏈表長度個數超過8個以後會轉換成紅黑樹,時間複雜度可以從O(n)降到O(logn)
    在這裏插入圖片描述

2.HashTable

1.底層哈希表;
2.鍵值不可重複,值可重複,無序;
3.線程安全;
4.鍵和值都不能爲null;
5.HashTable是遺留類,繼承自Dictionary類,雖然是線程安全,但併發性不如ConcurrentHashMap;

3.TreeMap

1.底層二叉樹;
2.有序,鍵值不可重複,值可重複;
3.繼承自SortedMap,默認對鍵進行升序排序,可以自定義Comparable接口,重定義排序規則;底層實現是紅黑樹(屬於排序樹的一種),加進去之後使用中序遍歷就可以得到由小到大的順序;
在這裏插入圖片描述
4.添加節點
a以根節點當前節點開始搜索。
b拿新節點的值和當前節點的值比較。
c如果新節點的值更大,則以當前節點的右子節點作爲新的當前節點;如果新節點的值更小,則以當前節點的左子節點作爲新的當前節點。
d重複 2、3 兩個步驟,直到搜索到合適的葉子節點爲止。
e將新節點添加爲第 4 步找到的葉子節點的子節點;如果新節點更大,則添加爲右子節點;否則添加爲左子節點。

4.LinkedHashMap

1.HashMap的一個子類,保存了插入的順序,使用Iterator進行迭代時,得到數據跟插入的順序一樣;
2.哈希表通過Iterator得到的數據就是無序的,比如HashSet,HashMap,因爲他們插入的時候沒有像數組一樣記錄順序;
3.底層是HashMap和雙向鏈表合二爲一;
如何實現,雙向鏈表的節點圖如下,before,after和next的區別是前者可以連接不同hash之間的鏈表,只要將數據put到雙向鏈表中,就可以實現按插入順序訪問該結構;
4.該集合有兩種遍歷方式,
訪問順序遍歷: 每次訪問完map中的元素後,會將該元素置入map的最後一位;
插入順序遍歷: 按插入時的順序遍歷
圖片取自https://blog.csdn.net/a724888/article/details/80290276
在這裏插入圖片描述
圖片取自https://blog.csdn.net/fengdongsuixin/article/details/95758243
在這裏插入圖片描述
5. 留個問題?LinkedHashMap如何實現LRU緩存?

5.ConcurrentHashMap

  1. ConcurrentHashMap 是一個 Segment 數組,Segment 通過繼承ReentrantLock 來進行加鎖,所以每次需要加鎖的操作鎖住的是一個 segment,這樣只要保證每個 Segment 是線程安全的,也就實現了全局的線程安全。
  2. concurrencyLevel:segment數。默認是 16,
    也就是說 ConcurrentHashMap 有 16 個 Segments,所以理論上,這個時候,最多可以同時支持 16 個線程併發寫,只要它們的操作分別分佈在不同的 Segment 上。這個值可以在初始化的時候設置爲其他值,但是一旦初始化以後,它是不可以擴容的。
    在這裏插入圖片描述
  3. Java8引入紅黑樹,同HashMap一樣;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章