java集合包整理

2021-09-24 21:57:57 字數 4697 閱讀 5751

1.集合包

集合包最常用的有collection和map兩個介面的實現類,colleciton用於存放多個單物件,map用於存放key-value形式的鍵值對。

collection中最常用的又分為兩種型別的介面:list和set,兩者最明顯的差別為list支援放入重複的元素,而set不支援。

list最常用的實現類有:arraylist、linkedlist、vector及stack;set介面常用的實現類有:hashset、treeset。

1.1 arraylist

arraylist基於陣列方式實現,預設構造器通過呼叫arraylist(int)來完成建立,傳入的值為10,例項化了乙個object陣列,並將此陣列賦給了當前例項的elementdata屬性,此object陣列的大小即為傳入的initialcapacity,因此呼叫空構造器的情況下會建立乙個大小為10的object陣列。

插入物件:add(e)

基於已有元素數量加1作為名叫mincapacity的變數,比較此值和object陣列的大小,若大於陣列值,那麼先將當前object陣列值賦給乙個陣列物件,接著產生乙個鑫的陣列容量值。此值的計算方法為當前陣列值*1.5+1,如得出的容量值仍然小於mincapacity,那麼就以mincapacity作為新的容量值,呼叫arrays.copyof來生成新的陣列物件。

還提供了add(int,e)這樣的方法將元素直接插入指定的int位置上,將目前index及其後的資料都往後挪一位,然後才能將指定的index位置的賦值為傳入的物件,這種方式要多付出一次複製陣列的代價。還提供了addall

刪除物件:remove(e)

這裡呼叫了faseremove方法將index後的物件往前複製一位,並將陣列中的最後乙個元素的值設定為null,即釋放了對此物件的引用。 還提供了remove(int)方法來刪除指定位置的物件,remove(int)的實現比remove(e)多了乙個陣列範圍的檢測,但少了物件位置的查詢,因此效能會更好。

獲取單個物件:get(int)

遍歷物件:iterator()

判斷物件是否存在:contains(e)

總結:1,arraylist基於陣列方式實現,無容量的限制;

2,arraylist在執行插入元素時可能要擴容,在刪除元素時並不會減小陣列的容量(如希望相應的縮小陣列容量,可以呼叫arraylist的trimtosize()),在查詢元素時要遍歷陣列,對於非null的元素採取equals的方式尋找;

3,arraylist是非執行緒安全的。

1.2 linkedlist

linkedlist基於雙向鍊錶機制,所謂雙向鍊錶機制,就是集合中的每個元素都知道其前乙個元素及其後乙個元素的位置。在linkedlist中,以乙個內部的entry類來代表集合中的元素,元素的值賦給element屬性,entry中的next屬性指向元素的後乙個元素,entry中的previous屬性指向元素的前乙個元素,基於這樣的機制可以快速實現集合中元素的移動。

總結:1,linkedlist基於雙向鍊錶機制實現;

2,linkedlist在插入元素時,須建立乙個新的entry物件,並切換相應元素的前後元素的引用;在查詢元素時,須遍歷鍊錶;在刪除元素時,要遍歷鍊錶,找到要刪除的元素,然後從鍊錶上將此元素刪除即可,此時原有的前後元素改變引用連在一起;

3,linkedlist是非執行緒安全的。

1.3 vector

其add、remove、get(int)方法都加了synchronized關鍵字,預設建立乙個大小為10的object陣列,並將capacityincrement設定為0。容量擴充策略:如果capacityincrement大於0,則將object陣列的大小擴大為現有size加上capacityincrement的值;如果capacity等於或小於0,則將object陣列的大小擴大為現有size的兩倍,這種容量的控制策略比arraylist更為可控。

vector是基於synchronized實現的執行緒安全的arraylist,但在插入元素時容量擴充的機制和arraylist稍有不同,並可通過傳入capacityincrement來控制容量的擴充。

1.4 stack

stack繼承於vector,在其基礎上實現了stack所要求的後進先出(lifo)的彈出與壓入操作,其提供了push、pop、peek三個主要的方法:

push操作通過呼叫vector中的addelement來完成;

pop操作通過呼叫peek來獲取元素,並同時刪除陣列中的最後乙個元素;

peek操作通過獲取當前object陣列的大小,並獲取陣列上的最後乙個元素。

1.5 hashset

預設構造建立乙個hashmap物件

add(e):呼叫hashmap的put方法來完成此操作,將需要增加的元素作為map中的key,value則傳入乙個之前已建立的object物件。

remove(e):呼叫hashmap的remove(e)方法完成此操作。

contains(e):hashmap的containskey

iterator():呼叫hashmap的keyset的iterator方法。

hashset不支援通過get(int)獲取指定位置的元素,只能自行通過iterator方法來獲取。

總結:1,hashset基於hashmap實現,無容量限制;

2,hashset是非執行緒安全的。

1.6 treeset

treeset和hashset的主要不同在於treeset對於排序的支援,treeset基於treemap實現。

1.7 hashmap

hashmap空構造,將loadfactor設為預設的0.75,threshold設定為12,並建立乙個大小為16的entry物件陣列。

基於陣列+鍊錶的結合體(鍊錶雜湊)實現,將key-value看成乙個整體,存放於entity陣列,put的時候根據key hash後的hashcode和陣列length-1按位與的結果值判斷放在陣列的哪個位置,如果該陣列位置上若已經存放其他元素,則在這個位置上的元素以鍊錶的形式存放。如果該位置上沒有元素則直接存放。

當系統決定儲存hashmap中的key-value對時,完全沒有考慮entry中的value,僅僅只是根據key來計算並決定每個entry的儲存位置。我們完全可以把map集合中的value當成key的附屬,當系統決定了key的儲存位置之後,value隨之儲存在那裡即可。get取值也是根據key的hashcode確定在陣列的位置,在根據key的equals確定在鍊錶處的位置。

1 while (capacity < initialcapacity)

2      capacity <<= 1;

以上**保證了初始化時hashmap的容量總是2的n次方,即底層陣列的長度總是為2的n次方。它通過h & (table.length -1) 來得到該物件的儲存位,若length為奇數值,則與運算產生相同結果,便會形成鍊錶,盡可能的少出現鍊錶才能提公升hashmap的效率,所以這是hashmap速度上的優化。

擴容resize():

當hashmap中的元素越來越多的時候,hash衝突的機率也就越來越高,因為陣列的長度是固定的。所以為了提高查詢的效率,就要對hashmap的陣列進行擴容,而在hashmap陣列擴容之後,最消耗效能的點就出現了:原陣列中的資料必須重新計算其在新陣列中的位置,並放進去,這就是resize。那麼hashmap什麼時候進行擴容呢?當hashmap中的元素個數超過陣列大小*loadfactor時,就會進行陣列擴容,loadfactor的預設值為0.75,這是乙個折中的取值。

負載因子衡量的是乙個雜湊表的空間的使用程度,負載因子越大表示雜湊表的裝填程度越高,反之愈小。負載因子越大,對空間的利用更充分,然而後果是查詢效率的降低;如果負載因子太小,那麼雜湊表的資料將過於稀疏,對空間造成嚴重浪費。

hashmap的實現中,通過threshold欄位來判斷hashmap的最大容量。threshold就是在此loadfactor和capacity對應下允許的最大元素數目,超過這個數目就重新resize,以降低實際的負載因子。預設的的負載因子0.75是對空間和時間效率的乙個平衡選擇。

initialcapacity*2,成倍擴大容量,hashmap(int initialcapacity, float loadfactor):以指定初始容量、指定的負載因子建立乙個 hashmap。不設定引數,則初始容量值為16,預設的負載因子為0.75,不宜過大也不宜過小,過大影響效率,過小浪費空間。擴容後需要重新計算每個元素在陣列中的位置,是乙個非常消耗效能的操作,所以如果我們已經預知hashmap中元素的個數,那麼預設元素的個數能夠有效的提高hashmap的效能。

hashtable資料結構的原理大致一樣,區別在於put、get時加了同步關鍵字,而且hashtable不可存放null值。

在高併發時可以使用concurrenthashmap,其內部使用鎖分段技術,維持這鎖segment的陣列,在陣列中又存放著entity陣列,內部hash演算法將資料較均勻分布在不同鎖中。

總結:1,hashmap採用陣列方式儲存key、value構成的entry物件,無容量限制;

2,hashmap基於key hash尋找entry物件存放到陣列的位置,對於hash衝突採用鍊錶的方式解決;

3,hashmap在插入元素時可能會擴大陣列的容量,在擴大容量時須要重新計算hash,並複製物件到新的陣列中;

4,hashmap是非執行緒安全的。

詳細說明:

1.8 treemap

treemap基於紅黑樹的實現,因此它要求一定要有key比較的方法,要麼傳入comparator實現,要麼key物件實現comparable藉口。在put操作時,基於紅黑樹的方式遍歷,基於comparator來比較key應放在樹的左邊還是右邊,如找到相等的key,則直接替換掉value。

Java集合碎片整理 三

接著 二 come on treeset 可以實現去重和排序 public class tree class dog implements comparable public string tostring public int compareto object obj dog dog dog ob...

java集合知識碎片化整理

collection介面 collection可以說是處理物件集合的父介面,其下有兩個子介面分別是list和map。需要注意的是 map不是collection的子介面!這是一定要記住的喲 collection介面中的方法如下 這其中,我們可以看到有幾個常用的方法,比如方法add 新增乙個元素到集合...

Java集合基礎知識整理

長度區別 陣列長度固定,集合長度可變 內容不同 陣列只能是同一型別元素,集合可以儲存不同型別元素 元素的資料型別不同 陣列可以儲存基本型別和引用型別,集合只能儲存引用型別 物件 集合繼承關係圖 是所有collextion集合類的超類,是乙個抽象類 基本功能 public static void ma...