java主要集合類的資料結構學習

2021-07-26 06:39:14 字數 3039 閱讀 8816

在程式中,集合類每天都在使用,以致於某些**充斥著list和map,一直沒有機會整理下它們背後的實現原理。這幾天不太忙,正好可以看會**,補充下概念。 

和集合類的大致分類類似,下面我也分list,map和set來描述。 

一. list 

 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主要集合類的資料結構學習

在程式中,集合類每天都在使用,以致於某些 充斥著list和map,一直沒有機會整理下它們背後的實現原理。這幾天不太忙,正好可以看會 補充下概念。和集合類的大致分類類似,下面我也分list,map和set來描述。一 list arraylist維護著乙個物件陣列。如果呼叫new arraylist 後...

java主要集合類的資料結構

一 list arraylist維護著乙個物件陣列。如果呼叫new arraylist 後,它會預設初始乙個size 10的陣列。每次add操作都要檢查陣列容量,如果不夠,重新設定乙個初始容量1.5倍大小的新陣列,然後再把每個元素copy過去。在陣列中間插入或刪除,都要移動後面的所有元素。使用sys...

資料結構 集合類

2 linkedlist 3 hashmap 4 hashtable arraylist初始長度為0,當第一次呼叫add後,長度變為10,當陣列首次擴容的10個空間用完需要擴容後,會第二次走grow方法來擴容 每次擴容為1.5倍 它的底層是用陣列實現的,所以查詢速度相對linkedlist要快。li...