Java常用集合筆記
阿新 • • 發佈:2018-07-18
鏈表實現 重復元素 查找樹 equal 而是 模運算 ash 死循環 運算
最近事情比較少,閑暇之余溫習鞏固一下Java的一些基礎知識,並做一些筆記,
Java常用集合,
主要參考的這篇文章:Java常用集合
ArrayList/Vertor
1. ArrayList 的主要消耗是數組擴容以及在指定位置添加數據,在日常使用時最好是指定大小,盡量減少擴容。更要減少在指定位置插入數據的操作。 2. 使用了 transient 修飾,可以防止被自動序列化。由於 ArrayList 是基於動態數組實現的,所以並不是所有的空間都被使用。 ArrayList 只序列化了被使用的數據。 3. 當對象中自定義了 writeObject 和 readObject 方法時,JVM 會調用這兩個自定義方法來實現序列化與反序列化。 4. Voctor 也是實現於 List 接口,底層數據結構和 ArrayList 類似,也是一個動態數組存放數據。不過是在 add() 方法的時候使用 synchronize 進行同步寫數據,但是開銷較大,所以 Vector 是一個同步容器並不是一個並發容器。
LinkedList
1. LinkedList 底層是基於雙向鏈表實現的,也是實現了 List 接口
2. LinkedList 插入,刪除都是移動指針效率很高。
3. 查找需要進行遍歷查詢,效率較低。
HashMap
1. HashMap 底層是基於數組和鏈表實現的。其中有兩個重要的參數:容量、負載因子,容量的默認大小是 16,負載因子是 0.75,當 HashMap 的 size > 16*0.75 時就會發生擴容(容量和負載因子都可以自由調整)。發生擴容時會對所有元素進行rehash 2. put 方法:首先會將傳入的 Key 做 hash 運算計算出 hashcode,然後根據數組長度取模計算出在數組中的 index 下標。由於在計算中位運算比取模運算效率高的多,所以 HashMap 規定數組的長度為 2^n 。這樣用 2^n - 1 做位運算與取模效果一致,並且效率還要高出許多。由於數組的長度有限,所以難免會出現不同的 Key 通過運算得到的 index 相同,這種情況可以利用鏈表來解決,HashMap 會在 table[index]處形成鏈表,采用頭插法將數據插入到鏈表中。 3. get 方法:和 put 類似,也是將傳入的 Key 計算出 index ,如果該位置上是一個鏈表就需要遍歷整個鏈表,通過 key.equals(k) 來找到對應的元素。 4. 在並發環境下使用 HashMap 容易出現死循環。所以 HashMap 只能在單線程中使用,並且盡量的預設容量,盡可能的減少擴容。 5. 在 JDK1.8 中對 HashMap 進行了優化: 當 hash 碰撞之後寫入鏈表的長度超過了閾值(默認為8),鏈表將會轉換為紅黑樹。 ### 紅黑樹 1. 紅黑樹,一種二叉查找樹,但在每個結點上增加一個存儲位表示結點的顏色,可以是Red或Black。 2. 通過對任何一條從根到葉子的路徑上各個結點著色方式的限制,紅黑樹確保沒有一條路徑會比其他路徑長出倆倍,因而是接近平衡的。
HashSet
1. HashSet 是一個不允許存儲重復元素的集合。HashSet 的原理比較簡單,幾乎全部借助於 HashMap 來實現的。
LinkedHashMap
1. LinkedHashMap 其實就是對 HashMap 進行了拓展,使用了雙向鏈表來保證了順序性。
2. LinkedHashMap 的排序方式有兩種:根據寫入順序排序。根據訪問順序排序。其中根據訪問順序排序時,每次 get 都會將訪問的值移動到鏈表末尾,這樣重復操作就能得到一個按照訪問順序排序的鏈表。
Java常用集合筆記