1. 程式人生 > >JAVA的主要集合類的數據結構

JAVA的主要集合類的數據結構

hset 存儲 靜態 actor 二進制 linked move .com copy

集合類的大致分類:List,Map和Set。

一、 List

  1. ArrayList
    技術分享圖片
    ArrayList維護著一個對象數組。如果調用new ArrayList()後,它會默認初始一個size=10的數組。
    每次add操作都要檢查數組容量,如果不夠,重新設置一個初始容量1.5倍大小的新數組,然後再把每個元素copy過去。
    在數組中間插入或刪除,都要移動後面的所有元素。(使用System.arraycopy())
  2. LindedList
    LinkedList的實現是一個雙向鏈表。每個節點除含有元素外,還包含向前,向後的指針。
    新建一個LinkedList,生成一個頭節點(header,就是一個頭指針),它的元素為null。
    技術分享圖片
    它自包含,next和previous指針都指向自己。執行add(Object obj)方法後,會生成一個新節點:
    技術分享圖片
    Header節點的next指向鏈表的第一個節點,previous指向鏈表的最後一個節點,在這裏都是first。再增加一個對象,它的形狀像下面這樣:
    技術分享圖片
    現在是一個標準的雙向鏈表形狀。每個節點都有自己的next和previous指針。增加節點,只會對鏈表的指針進行操作,速度快。
    LinkedList實現了Deque,所以它有雙向隊列的特征,在鏈表兩端可增刪數據。使用index查找對象時,會以index和size/2比較,從前或從後向中間搜索。ListIterator可向前或向後叠代。
    比較ArrayList和LinkedList的結構,就可以得出:
    (1) ArrayList的remove和add(index, Object)操作代價高,需要移動後面的每個元素。
    (2) LinkedList的get(index)操作代價高,它要先循環遍歷list,找到Object

二、 Map

  1. HashMap
    HashMap的結構是一個散列桶,初始化時生成如下結構:
    技術分享圖片
    每個bucket包含一個Entry(map自定義的一種結構,包含一個往後的指針)的鏈表。在put(key, value)後,它的結構如下:
    技術分享圖片
    將key的hashcode再次散列,然後用這個hash和length-1進行按位與操作,得到bucket的index,然後檢查當前bucket的鏈表,有沒有這個key,如果有替換value,沒有則跟在鏈表的最後。
    允許key和value都可以是null
    Index=0的bucket存key=null的value,也可以是其它hashcode為0的項。
    初始容量必須為2的冪次(我的理解是,在生成index的時候有這樣的代碼:hase ^ (length - 1)),length – 1的二進制代碼為全1,則容易進行hash的設計)。
    如果兩個key散列後的index一樣的話,第一個key生成的Entry先存在桶中,第二個key生成的Entry會將第一個Entry設為自己的next,串起來。(如圖中,先put(yy, “first”),會將這個Entry設為bucket的第一項,後put(xx,”second”),則生成新Entry,它的next為key為yy的Entry,生成一個鏈表)。
    在put操作中,會比較threshold(capacity * load_factor,一個臨界值),如果size > threshold的話,生成一個當前bucket兩倍數量的buckets,然後把現有的數據重新散列到新bucket中。
    對HashMap叠代時,返回數據的順序是:index從0到length-1,循環遍歷每個bucket,把不為null的數據取出,每個bucket內的順序由鏈表的順序決定。而不是由插入數據決定。
  2. LinkedHashMap
    上面說過,Map的叠代不由插入順序決定。如果要保持這種順序呢?就要新增加一種結構來保持。
    技術分享圖片
    LinkedHashMap是HashMap的子類,增加一個雙向鏈表,用來存儲每個新加入的節點。在遍歷時,按鏈表的順序進行。其實差不多就是上面HashMap和LinkedList的和吧。

三、Set

  1. HashSet
    HashSet使用HashMap來保持元素。Key = 元素,value是一個公有的對象,對每個元素都一樣,在HashMap裏面key是惟一的,當然很適合於構造set集合。等同於用HashMap包裝了次,顯示Set自己的特性。
    最後還要提到集合類裏面一個很重要的類:Collections,它有很多自己獨特的靜態方法。當然它主要提供幾種特殊集合(List, Map,Set),可以調用靜態方法來獲得:Unmodifiable(不可修改集合,不可添加或刪除元素),Synchronize(保持同步集合,它的基本每個方法都加鎖,防止並發操作),Checked(聲明之始傳入特定類型,以後的操作都會驗證加入元素是否屬於已定類型),Singleton(集合中只包含一個元素)。它們都是通過包裝集合類中的抽象類獲得,產生不同的行為。

JAVA的主要集合類的數據結構