Java集合的總結

參考博客:
  http://www.jianshu.com/p/63e76826e852
  http://www.cnblogs.com/LittleHann/p/3690187.html
  https://github.com/pzxwhc/MineKnowContainer/issues/18
參數書籍
  《java編程思想》 第十一章

一張圖說明java集合類的組織關係 其中加粗的爲經常使用集合類

 

從上面的集合框架圖能夠看到,Java集合框架主要包括兩種類型的容器,一種是集合(Collection),存儲一個元素集合,另外一種是圖(Map),存儲鍵/值對映射。
Collection接口又有3種子類型,List、Set和Queue,再下面是一些抽象類,最後是具體實現類,經常使用的有ArrayList、LinkedList、HashSet、LinkedHashSet、HashMap、LinkedHashMap等等。
一:List集合
 List 接口是Collection 接口的一個子類,在Collection 基礎上擴充了方法。同時能夠對每一個元素插入的位置進行精確的控制,它的主要實現類有 ArrayList,Vector,LinkedList。

1.1 ArrayList
  ArrayList 實現了 List 接口,意味着能夠插入空值,也能夠插入重複的值,非同步 ,它是 基於數組 的一個實現。從源碼中的 DEFAULT_CAPACITY = 10 看出,其默認分配帶下是長度爲10的數組

   ArrayList 不適合 增刪操做很是多的操做, 首先能夠看到這句話: elementData = Arrays.copyOf(elementData, newCapacity); 須要知道的是, Arrays.copyOf 函數的內部實現是再建立一個數組,而後把舊的數組的值一個個複製到新數組中。當常常增長操做的時候,容量不夠的時候,就會進行上述的擴容操做,這樣性能天然就下來了。 或者說,當咱們在固定位置進行增刪的時候,都會進行 System.arraycopy(elementData, index, elementData, index + 1, size - index); 也是很是低效的。html

分析了低效出現的緣由,那麼咱們就能夠知道:若是咱們須要常常進行特定位置的增刪操做,那麼最好仍是不要用這個了,可是,若是咱們基本上沒有固定位置的增刪操做,最好是要預估數據量的大小,而後再初始化最小容量,這樣能夠有效的避免擴容。以下代碼:java

   ArrayList<Integer> arrayList = new ArrayList<Integer>(20);git

  ArrayList總結:github

    1. ArrayList 能夠插入空值,也能夠插入重複值
    2. ArrayList 是基於數組的時候,因此不少數組的特性也直接應用到了 ArrayList。
    3. ArrayList 的性能消耗主要來源於擴容和固定位置的增刪。
    4. ArrayList 建立的時候 須要考慮是否要初始化最小容量,以此避免擴容帶來的消耗。
    5. ArrayList不適合作 插入和刪除操做
    6.  ArrayList 不是線程安全的
1.2 Vector

  也是實現了 List 接口,因此也是 能夠插入空值,能夠插入重複的值。 它和 HashTable 同樣,是屬於一種同步容器,而不是一種併發容器。(參考《Java併發編程實戰》,相似CopyOnWriteArrayList,ConcurrentHashMap這種就屬於併發容器)算法

內部成員變量:編程

protected Object[] elementData;
public Vector() {
    this(10);
}

能夠看到,也是基於 數組的實現,初始化也是 10 個容量。 那麼,再來看看 add()方法是否和 ArrayList 相同。數組

public synchronized boolean add(E e) {
    modCount++;
    ensureCapacityHelper(elementCount + 1);
    elementData[elementCount++] = e;
    return true;
}

能夠看到,和 ArrayList 也是同樣的,只是加了 synchronized 進行同步, 其實不少其餘方法都是經過加 synchronized 來實現同步。安全

Vector總結:
  1. 能夠插入空值,也能夠插入重複值
  2. 也是基於數組的時候,因此不少數組的特性也直接應用到了 Vector。
  3. 性能消耗也主要來源於 擴容。
  4. 建立的時候 須要考慮是否要初始化最小容量,以此避免擴容帶來的消耗。
  5. 至關於 ArrayList 的線程安全版本,實現同步的方式 是經過 synchronized。
  6. Vector不適合作 插入和刪除操做
1.3 LinkedList 
  LinkedList 實現了 List 接口,因此LinkedList 也能夠放入重複的值,也能夠放入空值。LinkedList不支持同步。LinkedList 不一樣於ArrayList 和Vector,它是使用鏈表的數據結構,再也不是數組。
當進行增刪的時候,只須要改變指針,並不會像數組那樣出現總體數據的大規模移動,複製等消耗性能的操做。
  在學習數據結構的時候,咱們知道鏈表和數組的最大區別在於它們對元素的存儲方式的不一樣致使它們在對數據進行不一樣操做時的效率不一樣,ArrayList在作添加或者刪除的時候 效率要低於linkedList
但在作遍歷操做的時候,ArrayList要好於LinkedList


二:Set
  Set接口擴展自Collection,它與List的不一樣之處在於,規定Set的實例不包含重複的元素。在一個規則集內,必定不存在兩個相等的元素。AbstractSet是一個實現Set接口的抽象類,Set接口有三個具體實現類,分別是散列集HashSet、鏈式散列集LinkedHashSet和樹形集TreeSet。
set判斷兩個對象相同不是使用"=="運算符,而是根據equals方法
2.1 HashSet
  HashSet是Set接口的典型實現,HashSet使用HASH算法來存儲集合中的元素,所以具備良好的存取和查找性能。當向HashSet集合中存入一個元素時,HashSet會調用該對象的
 hashCode()方法來獲得該對象的hashCode值,而後根據該HashCode值決定該對象在HashSet中的存儲位置。 值得主要的是,HashSet集合判斷兩個元素相等的標準是兩個對象經過equals()方法比較相等,而且兩個對象的hashCode()方法的返回值相等 2.2 LinkedHashSet LinkedHashSet集合也是根據元素的hashCode值來決定元素的存儲位置,但和HashSet不一樣的是,它同時使用鏈表維護元素的次序,這樣使得元素看起來是以插入的順序保存的。
  當遍歷LinkedHashSet集合裏的元素時,LinkedHashSet將會按元素的添加順序來訪問集合裏的元素。 LinkedHashSet須要維護元素的插入順序,所以性能略低於HashSet的性能,但在迭代訪問Set裏的所有元素時(遍歷)將有很好的性能(鏈表很適合進行遍歷) 2.3 SortedSet 此接口主要用於排序操做,即實現此接口的子類都屬於排序的子類 2.4 TreeSet
   TreeSet擴展自AbstractSet,並實現了NavigableSet,AbstractSet擴展自AbstractCollection,樹形集是一個有序的Set,其底層是一顆樹,這樣就能從Set裏面提取一個有序序列了。
   在實例化TreeSet時,咱們能夠給TreeSet指定一個比較器Comparator來指定樹形集中的元素順序。樹形集中提供了不少便捷的方法。
2.5 EnumSet EnumSet是一個專門爲枚舉類設計的集合類,EnumSet中全部元素都必須是指定枚舉類型的枚舉值,該枚舉類型在建立EnumSet時顯式、或隱式地指定。EnumSet的集合元素也是有序的,
  它們以枚舉值在Enum類內的定義順序來決定集合元素的順序

三:Queue
  ueue用於模擬"隊列"這種數據結構(先進先出 FIFO)。隊列的頭部保存着隊列中存放時間最長的元素,隊列的尾部保存着隊列中存放時間最短的元素。新元素插入(offer)到隊列的尾部,
訪問元素(poll)操做會返回隊列頭部的元素,隊列不容許隨機訪問隊列中的元素。結合生活中常見的排隊就會很好理解這個概念 3.1PriorityQueue PriorityQueue並非一個比較標準的隊列實現,PriorityQueue保存隊列元素的順序並非按照加入隊列的順序,而是按照隊列元素的大小進行從新排序,這點從它的類名也能夠
     看出來 3.2 Deque Deque接口表明一個"雙端隊列",雙端隊列能夠同時從兩端來添加、刪除元素,所以Deque的實現類既能夠當成隊列使用、也能夠當成棧使用 3.2.1) ArrayDeque 是一個基於數組的雙端隊列,和ArrayList相似,它們的底層都採用一個動態的、可重分配的Object[]數組來存儲集合元素,當集合元素超出該數組的容量時,系統會在底層重
       新分配一個Object[]數組來存儲集合元素 3.2.2) LinkedList

四:map
 

實現類:HashMap、Hashtable、LinkedHashMap和TreeMap數據結構

HashMap併發

  HashMap是最經常使用的Map,它根據鍵的HashCode值存儲數據,根據鍵能夠直接獲取它的值,具備很快的訪問速度,遍歷時,取得數據的順序徹底是隨機的。由於鍵對象不能夠重複,因此HashMap最多隻容許一條記錄的鍵爲Null,容許多條記錄的值爲null,是非同步的。

Hashtable

  Hashtable與HashMap相似,是HashMap的線程安全版,它支持線程的同步,即任一時刻只有一個線程能寫Hashtable,所以也致使了Hashtale在寫入時會比較慢,他繼承自Dictionary類,不一樣的是它不容許記錄的鍵或者值爲null,同時效率較低。

ConcurrentHashMap

  線程安全,而且鎖分離。ConcurrentHashMap內部使用段(Segment)來表示這些不一樣的部分,每一個段其實就是一個小的hashtable,它們有本身的鎖。只要多個修改操做發生在不一樣的段上,它們就能夠併發進行。

LinkedHashMap

  LinkedHashMap保存了記錄的插入順序,在用Iteraor遍歷LinkedHashMap時,先獲得的記錄確定是先插入的,在遍歷的時候會比HashMap慢,有HashMap的所有特性。

TreeMap

  TreeMap實現了SortMap接口,可以把它保存的記錄根據鍵排序,默認是按鍵值的升序排序(天然順序),也能夠指定排序的比較器,當用Iterator遍歷TreeMap時,獲得的記錄是排過序的。不容許key值爲空,非同步的。

相關文章
相關標籤/搜索