集合總結
阿新 • • 發佈:2017-06-16
緩存 二叉 比較 ast 一定的 fin 對比 重寫 包含
數組:數據在內存是連續存放的,隨機訪問效率很高(根據索引值就可以直接定位到具體的元素)。插入和刪除效率低(重新分配、移動元素) 鏈表:數據在內存按需分配,隨機訪問效率低(必須從頭或尾,順著鏈接查找),插入和刪除效率高。 ArrayLis,底層是動態數組(ArrayList隨機訪問效率很高,但插入和刪除性能比較低) 添加元素的效率還可以,重新分配和拷貝數組的開銷被平攤了。 插入和刪除元素的效率比較低,因為需要移動元素。 擴容條件:需求大小 > 數組大小 擴容後:原容量1.5倍 LinkedList(底層是雙向鏈表,但是支持雙端隊列 (Deque)),它的特點與ArrayList幾乎正好相反:(LinkedList隨機訪問效率很低,但插入和刪除性能比較高) 實現了Deque接口,可以作為隊列、棧和雙端隊列使用。實現原理上,內部是一個雙向鏈表,並維護了長度、頭節點和尾節點。鏈表對LinkedList沒有限制長度,但有可能對其他的容器限制長度 數據結構: E item; Node<E> next; Node<E> prev; 棧和隊列底層實現都是鏈表。(此處可以看《算法》這本書94頁) 棧和隊列只是雙端隊列的特殊情況。數據結構如下: 棧: E item Node next 隊列: E item Node first E item Node last 鏈表:增刪易,查詢慢(必須從頭到尾,順著鏈接查找,效率比較低) 內存只需按需分配內存,插入和刪除時 需要修改前驅和後繼節點的鏈接 數組:增刪難(移動元素和擴容分配),查詢快(元素連續存放,可以直接隨機訪問) 內存需要分配額外空間,插入和刪除時 需要移動所有後續元素 棧只操作頭部,隊列兩端都操作(尾部只添加、頭部只查看和刪除) Queue:隊列 Deque:雙向隊列(裏面包含了棧的操作方法)。extends Queue 鏈表和雙向鏈表不是一回事,結構不一樣: 鏈表:item和下一個結點引用(後繼) 雙向鏈表:item、上一個結點引用(前驅)、下一個結點引用(後繼) 理解了LinkedList和ArrayList的特點,我們就能比較容易的進行選擇了,如果列表長度未知,添加、刪除操作比較多,尤其經常從兩端進行操作,而按照索引位置訪問相對比較少,則LinkedList就是比較理想的選擇。============================================================================================================================== HashMap:底層是 數組+單向鏈表,數據結構如下: final K key; V value; HashMapEntry<K,V> next; int hash; 擴容條件:size(實際鍵值對個數) >= 閥值( 閥值 = initialCapacity * loadFactor ) 擴容後:原容量2倍 如何存儲值:根據key計算hash值,根據hash值計算索引index,根據索引找到鏈表。在對應鏈表操作時也是先比較hash值,相同的話才用equals方法比較。 HashMap特點分析: HashMap實現了Map接口,內部使用數組鏈表和哈希的方式進行實現,這決定了它有如下特點:1 根據鍵保存和獲取值的效率都很高,為O(1),每個單向鏈表往往只有一個或少數幾個節點,根據hash值就可以直接快速定位。 2 HashMap中的鍵值對沒有順序,因為hash值是隨機的。 LinkedHashMap:extends HashMap ---> 所以底層是哈希表。另外還有一個就是雙向鏈表,每個鍵值對既位於哈希表中,也位於這個雙向鏈表中。 重點是理解這裏的鏈表,哈希表(數組+單向鏈表)是一個結構,雙向列表是另一個結構 雙向鏈表數據結構如下: LinkedHashMapEntry<K,V> before, after; 可以保持元素按 插入 或 訪問 有序,這與TreeMap按 鍵 排序不同。 所以LinkedHashMap支持兩種順序,一種是插入順序,另外一種是訪問順序。 插入順序:先添加的在前面,後添加的在後面,修改操作不影響順序。 訪問順序:是指get/put操作。對一個鍵執行get/put操作後,其對應的鍵值對會移到鏈表 末尾,所以,最末尾的是最近訪問的,最開始的是最久沒被訪問的,這種順序就是訪問順序。 LRU緩存:是一個通用的提升數據訪問性能的思路,用來保存常用數據。 特點:容量較小,但訪問更快。 緩存是相對而言的,相對的是主存,主存的容量更大、但訪問更慢。 緩存的基本假設是,數據會被多次訪問,一般訪問數據時,都先從緩存中找,緩存中沒有再從主存中找,找到後,再放入緩存,這樣,下次如果再找相同數據,訪問就快了。 替換算法:一般而言,緩存容量有限,不能無限存儲所有數據,如果緩存滿了,當需要存儲新數據時,就需要一定的策略將一些老的數據清理出去,這個策略一般稱為替換算法。LRU是一種流行的替換算法,它的全稱是Least Recently Used LinkedHashMap對容量沒有限制,因為removeEldestEntry默認返回false。但它可以被子類重寫,LRUCache重寫了該方法並返回true,所以LRUCache有容量限制。 TreeMap:相比於HashMap它有順序,底層是紅黑樹 結構示意圖: K key; V value; TreeMapEntry<K, V> left = null; TreeMapEntry<K, V> right = null; TreeMapEntry<K, V> parent; boolean color = BLACK; 排序二叉樹算法: 1 首先與根節點比較,如果相同,就找到了 2 如果小於根節點,則到左子樹中遞歸查找 3 如果大於根節點,則到右子樹中遞歸查找 如何保證按 鍵 順序? 1 鍵實現Comparable接口 2 創建TreeMap時,傳進去Comparator對象
集合總結