集合總結

數組:數據在內存是連續存放的,隨機訪問效率很高(根據索引值就能夠直接定位到具體的元素)。插入和刪除效率低(從新分配、移動元素)
鏈表:數據在內存按需分配,隨機訪問效率低(必須從頭或尾,順着連接查找),插入和刪除效率高。

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對象
相關文章
相關標籤/搜索