集合類
List
ArrayList底層是陣列,LinkedList底層是連結串列。陣列遍歷速度快,LinkedList增刪元素快。
在工作中一般就用ArrayList,而不用LinkedList,原因也很簡單:
-
在工作中,遍歷的需求比增刪多,即便是增加元素往往也只是從尾部插入元素,而ArrayList在尾部插入元素也是O(1)
-
ArrayList增刪沒有想象中慢,ArrayList的增刪底層呼叫的
copyOf()
被優化過,加上現代CPU對記憶體可以塊操作,普通大小的ArrayList增刪比LinkedList更快。
List集合常用的子類有三個:
-
ArrayList,底層資料結構是陣列。執行緒不安全
-
ArrayList是基於動態陣列實現的,在增刪時候,需要陣列的拷貝複製。
-
ArrayList的預設初始化容量是10,每次擴容時候增加原先容量的一半,也就是變為原來的1.5倍
-
刪除元素時不會減少容量,若希望減少容量則呼叫trimToSize()
-
它不是執行緒安全的。它能存放null值。
-
-
LinkedList,底層資料結構是連結串列。執行緒不安全
-
底層實現是雙向連結串列[雙向連結串列方便實現往前遍歷]
-
-
Vector,底層資料結構是陣列。執行緒安全,方法帶有synchronized
-
底層是陣列,現在已少用,被ArrayList替代,原因有兩個:
-
Vector所有方法都是同步,有效能損失
-
Vector初始length是10 超過length時 以100%比率增長,相比於ArrayList更多消耗記憶體。
-
Set
Set常用子類:
-
HashSet集合,底層資料結構是雜湊表(是一個元素為連結串列的陣列)
-
TreeSet集合,底層資料結構是紅黑樹(是一個自平衡的二叉樹),保證元素的排序方式
-
LinkedHashSet集合,底層資料結構由雜湊表和連結串列組成。
Map
散列表
散列表為每個物件計算出一個整數,稱為雜湊碼。根據這些計算出來的整數(雜湊碼)儲存在對應的位置上!在Java中,散列表用的是連結串列陣列實現的,每個列表稱之為桶
一個桶上可能會遇到被佔用的情況(hashCode雜湊碼相同,就儲存在同一個位置上)
-
此時需要用該物件與桶上的物件進行比較,看看該物件是否存在桶子上了~如果存在,就不添加了,如果不存在則新增到桶子上
-
當然了,如果hashcode函式設計得足夠好,桶的數目也足夠,這種比較是很少的~
-
在JDK1.8中,桶滿時會從連結串列變成平衡二叉樹
紅黑樹
紅黑樹用的是也是兩種方式來替代2-3樹不斷的節點交換操作:
-
旋轉:順時針旋轉和逆時針旋轉
-
反色:交換紅黑的顏色
-
這個兩個實現比2-3樹交換的節點(合併,分解)要方便一些
紅黑樹為了保持平衡,還有制定一些約束,遵守這些約束的才能叫做紅黑樹:
-
紅黑樹是二叉搜尋樹。
-
根節點是黑色。
-
每個葉子節點都是黑色的空節點(NIL節點)。
-
每個紅色節點的兩個子節點都是黑色。(從每個葉子到根的所有路徑上不能有兩個連續的紅色節點)
-
從任一節點到其每個葉子的所有路徑都包含相同數目的黑色節點(每一條樹鏈上的黑色節點數量(稱之為“黑高”)必須相等)。
HashMap和HashTable
從儲存結構和實現來講基本上都是相同的。它和HashMap的最大的不同是它是執行緒安全的,另外它不允許key和value為null。Hashtable是個過時的集合類,不建議在新程式碼中使用,不需要執行緒安全的場合可以用HashMap替換,需要執行緒安全的場合可以用ConcurrentHashMap替換
Queue佇列
不知道大家有沒有學過生產者和消費者模式,秋招面試的時候可能會讓你手寫一段這樣的程式碼。最簡單的方式就是用阻塞佇列去寫