1. 程式人生 > >java中三大集合類Map,Set,List的詳細介紹

java中三大集合類Map,Set,List的詳細介紹

在講Map,Set,List三大介面之前,我們先來了解下Set和List的父類介面Collection介面 一:Collection介面:是java.util包下的一個介面: 其中有一些主要的方法: size(); isEmpty(); clear(); contains( ); add(); remove(); 這幾個方法都比較常見,在這就不詳細介紹啦!! 還有一個特殊的方法,因為Collection介面擴充套件了Iteratable介面,所有實現Itreable介面的集合必須提供一個稱為iterator()的方法,所以Collection還有iterator()方法,用法如下
Iterator it=set/list.iterator(); while(it.hasNext( )){ AnyType item=it.next( ); System.out.println(item); } 這裡的set\list是List或者Set介面的例項,有上可見,此方法主要是用於遍歷的。 附:Collectionsjava.util包下的類,包含各種有關集合操作的靜態方法,可以理解成對繼承Collection的介面都有效。

Collections類中的常用方法:

(1)Collections.sort(list):給佇列list中的物件排序

(2)Collection.max(list):

取佇列中最大的物件;Collection.min(list):取佇列中最小的物件

(3)Collection.copy(list1,list2):如果list1.length>list2.length,那麼list1的前list2.length部分會被覆蓋;否則IndexOutOfBoundsException報錯。

List2list1的子列表:

(4)Collections.indexOfSubList(list, list2)第一次出現的位置

(5)Collections.lastIndexOfSubList(list, list2);最後一次出現的位置

二:

繼承Collection介面的有List和Set介面:

List:ArrayList和LinkedList

Set:TreeSet和HashSet

  1. <</span>spanstyle="font-family:Microsoft YaHei;font-size:12px;">世間上本來沒有集合,(只有陣列參考C語言)但有人想要,所以有了集合  
  2. 有人想有可以自動擴充套件的陣列,所以有了List  
  3. 有的人想有沒有重複的陣列,所以有了set  
  4. 有人想有自動排序的組數,所以有了TreeSet,TreeList,Tree**  
  5. 而幾乎有有的集合都是基於陣列來實現的.  
  6. 因為集合是對陣列做的封裝,所以,陣列永遠比任何一個集合要快  
  7. 但任何一個集合,比陣列提供的功能要多  
  8. 一:陣列聲明瞭它容納的元素的型別,而集合不宣告。這是由於集合以object形式來儲存它們的元素。  
  9. 二:一個數組例項具有固定的大小,不能伸縮。集合則可根據需要動態改變大小。  
  10. 三:陣列是一種可讀/可寫資料結構---沒有辦法建立一個只讀陣列。然而可以使用集合提供的ReadOnly方法,以只讀方式來使用集合。該方法將返回一個集合的只讀版本。</</span>span>
  • ArrayList() : 代表長度可以改變得陣列。可以對元素進行隨機的訪問,向ArrayList()中插入與刪除元素的速度慢。 
  • LinkedList(): 在實現中採用連結串列資料結構。插入和刪除速度快,訪問速度慢。

ArrayList() 和LinkedList()的詳細介紹與區別:

由於ArrayList()的底層是陣列實現的,因此查詢是基於索引的,查詢速度快,但是增加、刪除元素慢,原因是每增加、刪除一個元素的話,整個整體元素都要重新移動位置(當然增加、刪除的位置在最後那個位置除外

由於LinkedList(): 在實現中採用連結串列資料結構,因此查詢速度較慢,因為每次查詢都要從頭開始一個一個的找,但是增加、刪除元素的速度較快

ArrayList使用一個內建的陣列來儲存元素,這個陣列的起始容量是10.當陣列需要增長時,新的容量按如下公式獲得:新容量=(舊容量*3)/2+1,也就是說每一次容量大概會增長50%。這就意味著,如果你有一個包含大量元素的ArrayList物件,那麼最終將有很大的空間會被浪費掉,這個浪費是由ArrayList的工作方式本身造成的。如果沒有足夠的空間來存放新的元素,陣列將不得不被重新進行分配以便能夠增加新的元素。對陣列進行重新分配,將會導致效能急劇下降。如果我們知道一個ArrayList將會有多少個元素,我們可以通過構造方法來指定容量。我們還可以通過trimToSize方法在ArrayList分配完畢之後去掉浪費掉的空間。

ArrayList() 、LinkedList()和vector的區別:

Vector的api描述是:從jdk 1.2版本開始,該類被修正為實現List介面,併成為Java Collection集合框架的一員,區別於其他一些新的集合實現類,Vector是執行緒安全的。

ArrayList() 、LinkedList()是執行緒不安全的。

解決ArrayListLinkedList執行緒不安全這個問題通常有兩種方法(個人認為)

一:使用synchronized關鍵字,這個大家應該都很熟悉了,不解釋了;

二:使用Collections.synchronizedList();使用方法如下:

        假如你建立的程式碼如下:List> data=new ArrayList>();

        那麼為了解決這個執行緒安全問題你可以這麼使用Collections.synchronizedList(),如:

        List> data=Collections.synchronizedList(new ArrayList>());

  • HashSet: HashSet類按照雜湊演算法來存取集合中的物件,存取速度比較快 
  • TreeSet :TreeSet類實現了SortedSet介面,能夠對集合中的物件進行排序HashSet:為快速查詢設計的Set。存入HashSet的物件必須定義hashCode()。 TreeSet: 儲存次序的Set, 底層為樹結構。使用它可以從Set中提取有序的序列。 
  • LinkedHashSet:具有HashSet的查詢速度,且內部使用連結串列維護元素的順序(插入的次序)。於是在使用迭代器遍歷Set時,結果會按元素插入的次序顯示。

Set介面

Set不允許包含相同的元素,如果試圖把兩個相同元素加入同一個集合中,add方法返回false。
Set判斷兩個物件相同不是使用==運算子,而是根據equals方法。也就是說,只要兩個物件用equals方法比較返回true,Set就不會接受這兩個物件。

HashSet
HashSet有以下特點
 不能保證元素的排列順序,順序有可能發生變化
 不是同步的
 集合元素可以是null,但只能放入一個null
當向HashSet結合中存入一個元素時,HashSet會呼叫該物件的hashCode()方法來得到該物件的hashCode值,然後根據 hashCode值來決定該物件在HashSet中儲存位置。
簡單的說,HashSet集合判斷兩個元素相等的標準是兩個物件通過equals方法比較相等,並且兩個物件的hashCode()方法返回值相等
注意,如果要把一個物件放入HashSet中,重寫該物件對應類的equals方法,也應該重寫其hashCode()方法。

其規則是如果兩個物件通過equals方法比較返回true時,其hashCode也應該相同。另外,物件中用作equals比較標準的屬性,都應該用來計算 hashCode的值。

LinkedHashSet
LinkedHashSet集合同樣是根據元素的hashCode值來決定元素的儲存位置,但是它同時使用連結串列維護元素的次序。這樣使得元素看起來像是以插入順序儲存的,也就是說,當遍歷該集合時候,LinkedHashSet將會以元素的新增順序訪問集合的元素。
LinkedHashSet在迭代訪問Set中的全部元素時,效能比HashSet好,但是插入時效能稍微遜色於HashSet。

TreeSet類
TreeSet是SortedSet介面的唯一實現類,TreeSet可以確保集合元素處於排序狀態。TreeSet支援兩種排序方式,自然排序和定製排序,其中自然排序為預設的排序方式。向TreeSet中加入的應該是同一個類的物件。
TreeSet
判斷兩個物件不相等的方式是兩個物件通過equals方法返回false,或者通過CompareTo方法比較沒有返回0

List和Set的區別:

Set是最簡單的一種集合。集合中的物件不按特定的方式排序,並且沒有重複物件。

Set的功能方法 

Set具有與Collection完全一樣的介面,因此沒有任何額外的功能,不像前面有兩個不同的List。實際上Set就是Collection,只是行為不同。(這是繼承與多型思想的典型應用:表現不同的行為。)Set不儲存重複的元素(至於如何判斷元素相同則較為負責) 

Set : 存入Set的每個元素都必須是唯一的,因為Set不儲存重複元素。加入Set的元素必須定義equals()方法以確保物件的唯一性。Set與Collection有完全一樣的介面。Set介面不保證維護元素的次序。

List的特徵是其元素以線性方式儲存,集合中可以存放重複物件。 次序是List最重要的特點:它保證維護元素特定的順序

注:Set物件不按特定的方式排序,而List它保證維護元素特定的順序最直接的證明是:往ArrayList物件和HashSet物件中新增相同順序的物件元素,不做任何排序處理,然後遍歷輸出,你會發現List的輸出順序呢是和輸入順序是一致的,而Set的輸出順序是不一致的。

Map:

HashMap

HashTable

TreeMap

HashMap和HashTable的區別:

我們先看2個類的定義

1. publicclass Hashtable  

2. extends Dictionary  

3. implements Map, Cloneable, java.io.Serializable  

1. publicclass HashMap  

2. extends AbstractMap  

3. implements Map, Cloneable, Serializable  

AbstractMap介面的直接子類:HashMapTreeMap

Hashtable

注意1 方法是同步的注意2 方法不允許value==null注意3 方法呼叫了keyhashCode方法,如果key==null,會丟擲空指標異常

HashMap

注意1 方法是非同步的注意2 最多隻能允許一條記錄的鍵為null,允許多條記錄的值為null

注意3 方法並沒有對value進行任何呼叫,所以允許為null

HashMapHashtablecontains方法去掉了,改成containsvaluecontainsKey。因為contains方法容易讓人引起誤解

2. HashTableHashMap區別

第一,繼承不同。

publicclass Hashtable extends Dictionary implements Mappublicclass HashMap  extends AbstractMap implements Map

第二

Hashtable 中的方法是同步的,而HashMap中的方法在預設情況下是非同步的。在多執行緒併發的環境下,可以直接使用Hashtable,但是要使用HashMap的話就要自己增加同步處理了。

第三

Hashtable中,keyvalue都不允許出現null值。

HashMap中,null可以作為鍵,這樣的鍵只有一個;可以有一個或多個鍵所對應的值為null。當get()方法返回null值時,即可以表示 HashMap中沒有該鍵,也可以表示該鍵所對應的值為null。因此,在HashMap中不能由get()方法來判斷HashMap中是否存在某個鍵,而應該用containsKey()方法來判斷。

第四,兩個遍歷方式的內部實現上不同。

HashtableHashMap都使用了 Iterator。而由於歷史原因,Hashtable還使用了Enumeration的方式。

HashMap的遍歷:

第一種:  Map map = new HashMap();  Iterator iter = map.entrySet().iterator();while (iter.hasNext()) {  Map.Entry entry = (Map.Entry) iter.next();  Object key = entry.getKey();  Object val = entry.getValue();  }  效率高,以後一定要使用此種方式!第二種:  Map map = new HashMap();  Iterator iter = map.keySet().iterator();while (iter.hasNext()) {  Object key = iter.next();  Object val = map.get(key);  }第三種:(實際上也是第二種)

Map map=new HashMap();

for(Integer key:map.keySet()){

System.out.println(key+" "+map.get(key));

}

第五

雜湊值的使用不同,HashTable直接使用物件的hashCode。而HashMap重新計算hash值。

第六

HashtableHashMap它們兩個內部實現方式的陣列的初始大小和擴容的方式。HashTablehash陣列預設大小是11,增加的方式是 old*2+1HashMaphash陣列的預設大小是16,而且一定是2的指數。

TreeSetTreeMap的區別:

TreeMap  TreeSet  Java Collection Framework 的兩個重要成員,其中 TreeMap  Map 介面的常用實現類,而 TreeSet  Set 介面的常用實現類。雖然TreeMap TreeSet 實現的介面規範不同,但 TreeSet 底層是通過 TreeMap 來實現的(如同HashSet底層是是通過HashMap來實現的一樣),因此二者的實現方式完全一樣。而 TreeMap 的實現就是紅黑樹演算法。

HashSet完全類似,TreeSet裡面絕大部分方法都市直接呼叫TreeMap方法來實現的

相同點:

TreeMapTreeSet都是有序的集合,也就是說他們儲存的值都是拍好序的。

TreeMapTreeSet都是非同步集合,因此他們不能在多執行緒之間共享,不過可以使用方法Collections.synchroinzedMap()來實現同步

執行速度都要比Hash集合慢,他們內部對元素的操作時間複雜度為O(logN),而HashMap/HashSet則為O(1)

不同點:

最主要的區別就是TreeSetTreeMap非別實現SetMap介面

TreeSet只儲存一個物件,而TreeMap儲存兩個物件KeyValue(僅僅key物件有序)

TreeSet中不能有重複物件,而TreeMap中可以存在

文章參考了一下幾位的部落格,如有侵權,請聯絡刪除:

http://blog.csdn.net/speedme/article/details/22661671