1. 程式人生 > >14. ArrayList、LinkedList、Vector的區別。

14. ArrayList、LinkedList、Vector的區別。

在區分這3個實現類的區別之前,必須清楚的知道集合框架。

集合框架從最高根介面開始分為兩層:

collection

├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set

Map
Hashtable
├HashMap
└WeakHashMap

其中List作為Collection的子介面。是一個有序的集合,元素可重複的儲存結構。而在這個子介面下有很多實現類。其中就有Arraylist,LinkedList、Vector。


主要介紹下 主要的幾個介面的型別:

Collection介面

Collection是最基本的集合介面,一個Collection代表一組Object,即Collection的元素(elements),一些Collection允許相同的元素而另一些不行。一些能排序而另一些不行。Java SDK不提供直接繼承自Collection的類,Java SDK提供的類都是繼承自Collection的“子介面”如List和Set。

在這裡介面下,有一個公共的介面Iterable。這個介面有一個遍歷迭代方法Iterator()

該方法返回一個迭代子,使用該迭代子即可逐一訪問Collection中每一個元素。典型的用法如下:
    Iterator it = collection.iterator(); // 獲得一個迭代子
    while(it.hasNext()) {
      Object obj = it.next(); // 得到下一個元素
    }

List介面

是一個有序的Collection。通過這個介面可以準確的插入每個元素的位置,使用者通過索引可以訪問在List中的元素,類似於java中的陣列,與Collection中的Set不同,其介面中的元素是容許有相同重複的。
  除了具有Collection介面必備的iterator()方法外,List還提供一個listIterator()方法,返回一個ListIterator介面,和標準的Iterator介面相比,ListIterator多了一些add()之類的方法,允許新增,刪除,設定元素,還能向前或向後遍歷。


  實現List介面的常用類有LinkedList,ArrayList,Vector和Stack。

Arraylist實現類

在List的基本定義下,是一個可變大小的陣列,容許所有元素,包括null。沒有同步。

在這裡類下,因為結構的原因,set(),get(),size,isempty等方法時間複雜度都是常數,因為陣列是有下標的。但是在add這種方法下,就需要0(n)的時間,因為需要從頭遍歷到尾。

其中這個儲存空間是有一個容量的,根據不斷增加的元素會自動增加,當需要插入大量元素時,在插入前可以呼叫ensureCapacity方法來增加ArrayList的容量以提高插入效率。

LinkedLik

st實現類

首先要清楚的是,LinkedLlist是實現List和Queue(佇列介面)

LinkedList使用雙向連結串列實現儲存,按序號索引資料需要進行向前或向後遍歷,但是插入資料時只需要記錄本項前後項即可,插入資料較快。

LinkedList是通過節點直接彼此連線來實現的。每一個節點都包含前一個節點的引用,後一個節點的引用和節點儲存的值。當一個新節點插入時,只需要修改其中保持先後關係的節點的引用即可,當刪除記錄時也一樣。這樣就帶來以下有缺點:
操作其中物件的速度快 只需要改變連線,新的節點可以在記憶體中的任何地方
不能隨即訪問 雖然存在get()方法,但是這個方法是通過遍歷接點來定位的所以速度慢

Vector實現類

Vector非常類似ArrayList,但是Vector是同步的。由Vector建立的Iterator,雖然和ArrayList建立的Iterator是同一介面,但是,因為Vector是同步的,當一個Iterator被建立而且正在被使用,另一個執行緒改變了Vector的狀態(例如,新增或刪除了一些元素),這時呼叫Iterator的方法時將丟擲ConcurrentModificationException,因此必須捕獲該異常。

 ArrayList、LinkedList與Vector的對比
從圖中可以看出,這三者都實現了List 介面.所有使用方式也很相似,主要區別在於因為實現方式的不同,所以對不同的操作具有不同的效率。
ArrayList 是一個可改變大小的陣列.當更多的元素加入到ArrayList中時,其大小將會動態地增長.內部的元素可以直接通過get與set方法進行訪問,因為ArrayList本質上就是一個數組.
LinkedList 是一個雙鏈表,在新增和刪除元素時具有比ArrayList更好的效能.但在get與set方面弱於ArrayList.
當然,這些對比都是指資料量很大或者操作很頻繁的情況下的對比,如果資料和運算量很小,那麼對比將失去意義.
Vector 和ArrayList類似,但屬於強同步類。如果你的程式本身是執行緒安全的(thread-safe,沒有在多個執行緒之間共享同一個集合/物件),那麼使用ArrayList是更好的選擇。
Vector和ArrayList在更多元素新增進來時會請求更大的空間。Vector每次請求其大小的雙倍空間,而ArrayList每次對size增長50%.
 LinkedList 還實現了 Queue 介面,該介面比List提供了更多的方法,包括 offer(),peek(),poll()等.
注意: 預設情況下ArrayList的初始容量非常小,所以如果可以預估資料量的話,分配一個較大的初始值屬於最佳實踐,這樣可以減少調整大小的開銷。