1. 程式人生 > >thinking in java (十) ----- 集合

thinking in java (十) ----- 集合

我們除了最常用的八種基本型別,String型別,還有集合類Collection,常見的有ArrayList,HahsMap,HashSet,也有不常用的stack,queue,有執行緒安全的Vector,HashTable,也有執行緒不安全的LinkedList,TreeMap等。

Collection介面 

這是最基本的集合介面,不提供直接的實現,聲明瞭適用於JAVA集合(只包括Set和List)的通用方法。Map介面並不是Collection介面的子介面,但是它仍然被看作是Collection框架的一部分。

圖中可以看到collection介面是由兩個子介面Set和List外加一個不是子介面的Map組成,

List:可以通過index來獲取元素,它允許元素的重複,ArrayList,LinkedList,Vector實現List介面。

Set:不允許元素的重複,HashSet,TreeSet實現Set介面

Map:使用鍵值對方式儲存,值可以重複,鍵不可以重複,子介面Hashmap,Hashtable,TreeMap

List介面

List是Collection的直接子介面,也不提供直接的實現,List代表的是有序的Collection,即它用某種特定的插入順序來維護元素順序,使用者可以對列表中每個元素插入位置進行精確地控制,同時根據元素的索引訪問元素。實現List介面的集合主要有ArrayList,LinkedList,Vector,Stack。

  • ArrayList

ArrayList是一個動態陣列,也是最常用的集合,繼承自AbstractList,,實現List介面。底層基於陣列實現容量大小的動態變化,最初的容量預設是10,在每次向容器中增加元素的同時都會進行容量檢查,當快溢位時,就會進行擴容操作,他允許任何符合規則的元素插入甚至包括null,同時還實現了RandomAccess,Cloneable,Serializable介面,所以ArrayList是支援快速訪問,複製,序列化的。

ArrayList擅長隨機訪問,同時ArrayList是非同步的。

  • LinkedList

同樣實現List介面的LinkedList和ArrayList不同,ArrayList是一個動態陣列,而LinkedList是一個雙向連結串列,所以它除了ArrayList的基本操作外,還額外提供了get,remove,insert方法在LinkedList首部或者尾部。

由於實現方式不同,LinkedList不能隨機訪問,他所有的操作都是按照雙向連結串列的需要執行,在列表索引的操作將從開頭或者結尾遍歷列表,這樣做的好處是可以通過較低的代價在List中進行插入和刪除操作。

與ArrayList一樣,LinkedList也是非同步。如果是非同步問題的話,就涉及到多執行緒。如果多執行緒同時訪問一個List,則必須自己先實現訪問同步,一種方法就是在建立List的時候構造一個同步的List:List list = Collection.synchronizedList(new LinkedList(....))

  • Vector

與ArrayList相似,但是Vector是同步的執行緒安全,的動態陣列,它的操作和ArrayList幾乎一樣。

  • Stack

幾乎沒有用過鴨,

Set介面

set是一種不包括重複元素的Collection。實現了

  • EnumSet

列舉的Set,所有的元素都是列舉元素

  • HashSet

HashSet堪稱查詢速度最快的集合,因為其內部是HashCode來實現的,(需要重寫hashcode和equals方法),所以不保證set的迭代順序,特別是他不保證順序永恆不變

  • TreeSet

沒有用到過。

Map介面

Map和List,set介面不同,他是一些列鍵值對組成的集合,提供 了K到V的對映,同時他沒有繼承Collection。在Map中保證了KV的一一對應,所以K不能相同,V可以相同。實現的Map有:hashmap,treemap,hashtable,properties,enumMap

  • HashMap

這個是用的最多的,以hash表資料結構實現,查詢物件通過雜湊函式計算位置,他是為了快速查詢設計的,其內部定義了一個hash陣列(Entry[] table),元素會通過hash轉換函式將hash地址轉換為陣列中存放的索引,如果有衝突,就使用雜湊連結串列的形式將所有相同hash地址的元素串起來,可能通過檢視HashMap.Entry的原始碼,他是一個單鏈表結構

  • TreeMap

不會

  • HashTable

也是以雜湊資料結構實現的,解決衝突時與HashMap一樣採用雜湊連結串列的形式,不過效能比hashmap低

Queue

不會

異同點

  • Vector和ArrayList

 1,vector是執行緒同步的,所以它也是執行緒安全的,而arraylist是執行緒非同步的,是不安全的。如果不考慮到執行緒的安全因素,一般用arraylist效率比較高。 
 2,如果集合中的元素的數目大於目前集合陣列的長度時,vector增長率為目前陣列長度的100%,而arraylist增長率為目前陣列長度的50%.如果在集合中使用資料量比較大的資料,用vector有一定的優勢。 
 3,如果查詢一個指定位置的資料,vector和arraylist使用的時間是相同的,都是0(1),這個時候使用vector和arraylist都可以。而如果移動一個指定位置的資料花費的時間為0(n-i)n為總長度,這個時候就應該考慮到使用linklist,因為它移動一個指定位置的資料所花費的時間為0(1),而查詢一個指定位置的資料時花費的時間為0(i)。

      ArrayList 和Vector是採用陣列方式儲存資料,此陣列元素數大於實際儲存的資料以便增加和插入元素,都允許直接序號索引元素,但是插入資料要設計到陣列元素移動等記憶體操作,所以索引資料快插入資料慢,Vector由於使用了synchronized方法(執行緒安全)所以效能上比ArrayList要差,LinkedList使用雙向連結串列實現儲存,按序號索引資料需要進行向前或向後遍歷,但是插入資料時只需要記錄本項的前後項即可,所以插入數度較快!

  • ArrayList和linkedList

      1.ArrayList是實現了基於動態陣列的資料結構,LinkedList基於連結串列的資料結構。 
      2.對於隨機訪問get和set,ArrayList覺得優於LinkedList,因為LinkedList要移動指標。 
      3.對於新增和刪除操作add和remove,LinedList比較佔優勢,因為ArrayList要移動資料。 
      這一點要看實際情況的。若只對單條資料插入或刪除,ArrayList的速度反而優於LinkedList。但若是批量隨機的插入刪除資料,LinkedList的速度大大優於ArrayList. 因為ArrayList每插入一條資料,要移動插入點及之後的所有資料。

  • HashMap和TreeMap

       1、HashMap通過hashcode對其內容進行快速查找,而TreeMap中所有的元素都保持著某種固定的順序,如果你需要得到一個有序的結果你就應該使用TreeMap(HashMap中元素的排列順序是不固定的)。HashMap中元素的排列順序是不固定的)。

      2、  HashMap通過hashcode對其內容進行快速查詢,而TreeMap中所有的元素都保持著某種固定的順序,如果你需要得到一個有序的結果你就應該使用TreeMap(HashMap中元素的排列順序是不固定的)。集合框架”提供兩種常規的Map實現:HashMap和TreeMap (TreeMap實現SortedMap介面)。

      3、在Map 中插入、刪除和定位元素,HashMap 是最好的選擇。但如果您要按自然順序或自定義順序遍歷鍵,那麼TreeMap會更好。使用HashMap要求新增的鍵類明確定義了hashCode()和 equals()的實現。 這個TreeMap沒有調優選項,因為該樹總處於平衡狀態。

  • HashTable和HashMap

      1、歷史原因:Hashtable是基於陳舊的Dictionary類的,HashMap是Java 1.2引進的Map介面的一個實現 。

      2、同步性:Hashtable是執行緒安全的,也就是說是同步的,而HashMap是執行緒序不安全的,不是同步的

      3、值:只有HashMap可以讓你將空值作為一個表的條目的key或value 。

對集合的選擇

  • 對List的選擇

     1、對於隨機查詢與迭代遍歷操作,陣列比所有的容器都要快。所以在隨機訪問中一般使用ArrayList

      2、LinkedList使用雙向連結串列對元素的增加和刪除提供了非常好的支援,而ArrayList執行增加和刪除元素需要進行元素位移。

      3、對於Vector而已,我們一般都是避免使用。

      4、將ArrayList當做首選,畢竟對於集合元素而已我們都是進行遍歷,只有當程式的效能因為List的頻繁插入和刪除而降低時,再考慮LinkedList。

  • 對Set的選擇

      1、HashSet由於使用HashCode實現,所以在某種程度上來說它的效能永遠比TreeSet要好,尤其是進行增加和查詢操作。

      3、雖然TreeSet沒有HashSet效能好,但是由於它可以維持元素的排序,所以它還是存在用武之地的。

  • 對Map的選擇

     1、HashMap與HashSet同樣,支援快速查詢。雖然HashTable速度的速度也不慢,但是在HashMap面前還是稍微慢了些,所以HashMap在查詢方面可以取代HashTable。

     2、由於TreeMap需要維持內部元素的順序,所以它通常要比HashMap和HashTable慢。