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

來源:互聯網
上載者:User

在程式中,集合類每天都在使用,以致於某些代碼充斥著List和Map,一直沒有機會整理下它們背後的實現原理。這幾天不太忙,正好可以看會代碼,補充下概念。 
和集合類的大致分類類似,下面我也分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的結構是一個散列桶,桶內的每一個索引值對(key/value)稱為一個元素(entry),當有多個元素時,通過鏈錶鏈接起來。初始化時產生如下結構 

 
每個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的和吧。 

區別:
1、HashMap裡面存入的索引值對在取出的時候是隨機的,是我們最常用的一個Map。它根據鍵的HashCode值儲存資料,根據鍵可以直接擷取它的值,具有很快的訪問速度。在Map 中插入、刪除和定位元素,HashMap 是最好的選擇。

2、 LinkedHashMap 繼承了HashMap,如果需要輸出的順序和插入的相同,那麼用LinkedHashMap可以實現;LinkedHashMap還可以通過設定accessOrder為true來實現LRU順序的輸出。

3、TreeMap取出來的是排序後的索引值對。但如果要按自然順序或自訂順序遍曆鍵,那麼TreeMap是一個很好的選擇。 

 

三.Set 
1).HashSet 
HashSet使用HashMap來保持元素。Key = 元素,value是一個公有的對象,對每個元素都一樣,在HashMap裡面key是惟一的,當然很適合於構造set集合。等同於用HashMap封裝了次,顯示Set自己的特性。 

最後還要提到集合類裡面一個很重要的類:Collections,它有很多自己獨特的靜態方法。當然它主要提供幾種特殊集合(List, Map,Set),可以調用靜態方法來獲得:Unmodifiable*(不可修改集合,不可添加或刪除元素),Synchronize*(保持同步集合,它的基本每個方法都加鎖,防止並行作業),Checked*(聲明之始傳入特定類型,以後的操作都會驗證加入元素是否屬於已定類型),Singleton*(集合中只包含一個元素)。它們都是通過封裝集合類中的抽象類別獲得,產生不同的行為。 

上面是常見的幾種集合類,其它類我很少使用到。

原文連結:http://langyu.iteye.com/blog/360728

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.