java中三大集合類Map,Set,List的詳細介紹
Collections類中的常用方法:
(1)Collections.sort(list):給佇列list中的物件排序
(2)Collection.max(list):
(3)Collection.copy(list1,list2):如果list1.length>list2.length,那麼list1的前list2.length部分會被覆蓋;否則IndexOutOfBoundsException報錯。
List2是list1的子列表:
(4)Collections.indexOfSubList(list, list2)第一次出現的位置
(5)Collections.lastIndexOfSubList(list, list2);最後一次出現的位置
二:
繼承Collection介面的有List和Set介面:
List:ArrayList和LinkedList
Set:TreeSet和HashSet
- <</span>spanstyle="font-family:Microsoft YaHei;font-size:12px;">世間上本來沒有集合,(只有陣列參考C語言)但有人想要,所以有了集合
- 有人想有可以自動擴充套件的陣列,所以有了List
- 有的人想有沒有重複的陣列,所以有了set
- 有人想有自動排序的組數,所以有了TreeSet,TreeList,Tree**
- 而幾乎有有的集合都是基於陣列來實現的.
- 因為集合是對陣列做的封裝,所以,陣列永遠比任何一個集合要快
- 但任何一個集合,比陣列提供的功能要多
- 一:陣列聲明瞭它容納的元素的型別,而集合不宣告。這是由於集合以object形式來儲存它們的元素。
- 二:一個數組例項具有固定的大小,不能伸縮。集合則可根據需要動態改變大小。
- 三:陣列是一種可讀/可寫資料結構---沒有辦法建立一個只讀陣列。然而可以使用集合提供的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()是執行緒不安全的。
解決ArrayList和LinkedList執行緒不安全這個問題通常有兩種方法(個人認為)
一:使用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介面的直接子類:HashMap和TreeMap
Hashtable
注意1 方法是同步的注意2 方法不允許value==null注意3 方法呼叫了key的hashCode方法,如果key==null,會丟擲空指標異常
HashMap
注意1 方法是非同步的注意2 最多隻能允許一條記錄的鍵為null,允許多條記錄的值為null
注意3 方法並沒有對value進行任何呼叫,所以允許為null
HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因為contains方法容易讓人引起誤解
2. HashTable和HashMap區別
第一,繼承不同。
publicclass Hashtable extends Dictionary implements Mappublicclass HashMap extends AbstractMap implements Map
第二
Hashtable 中的方法是同步的,而HashMap中的方法在預設情況下是非同步的。在多執行緒併發的環境下,可以直接使用Hashtable,但是要使用HashMap的話就要自己增加同步處理了。
第三
Hashtable中,key和value都不允許出現null值。
在HashMap中,null可以作為鍵,這樣的鍵只有一個;可以有一個或多個鍵所對應的值為null。當get()方法返回null值時,即可以表示 HashMap中沒有該鍵,也可以表示該鍵所對應的值為null。因此,在HashMap中不能由get()方法來判斷HashMap中是否存在某個鍵,而應該用containsKey()方法來判斷。
第四,兩個遍歷方式的內部實現上不同。
Hashtable、HashMap都使用了 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值。
第六
Hashtable和HashMap它們兩個內部實現方式的陣列的初始大小和擴容的方式。HashTable中hash陣列預設大小是11,增加的方式是 old*2+1。HashMap中hash陣列的預設大小是16,而且一定是2的指數。
TreeSet與TreeMap的區別:
TreeMap 和 TreeSet 是 Java Collection Framework 的兩個重要成員,其中 TreeMap 是 Map 介面的常用實現類,而 TreeSet 是 Set 介面的常用實現類。雖然TreeMap 和TreeSet 實現的介面規範不同,但 TreeSet 底層是通過 TreeMap 來實現的(如同HashSet底層是是通過HashMap來實現的一樣),因此二者的實現方式完全一樣。而 TreeMap 的實現就是紅黑樹演算法。
與HashSet完全類似,TreeSet裡面絕大部分方法都市直接呼叫TreeMap方法來實現的
相同點:
TreeMap和TreeSet都是有序的集合,也就是說他們儲存的值都是拍好序的。
TreeMap和TreeSet都是非同步集合,因此他們不能在多執行緒之間共享,不過可以使用方法Collections.synchroinzedMap()來實現同步
執行速度都要比Hash集合慢,他們內部對元素的操作時間複雜度為O(logN),而HashMap/HashSet則為O(1)。
不同點:
最主要的區別就是TreeSet和TreeMap非別實現Set和Map介面
TreeSet只儲存一個物件,而TreeMap儲存兩個物件Key和Value(僅僅key物件有序)
TreeSet中不能有重複物件,而TreeMap中可以存在
文章參考了一下幾位的部落格,如有侵權,請聯絡刪除:
http://blog.csdn.net/speedme/article/details/22661671