淺談Vector、ArrayList、LinkedList


下圖是Collection的類繼承圖

從圖中可以看出:Vector、ArrayList、LinkedList這三者都實現了List 接口.所有使用方式也很相似,主要區別在於實現方式的不同,所以對不同的操作具有不同的效率。

ArrayList  就是動態數組,是Array的復雜版本,動態的增加和減少元素.當更多的元素加入到ArrayList中時,其大小將會動態地增長。

Vector 和ArrayList類似, 區別在於Vector是同步類(synchronized).因此,開銷就比ArrayList要大。

LinkedList 是一個雙鏈表,在添加和刪除元素時具有比ArrayList更好的性能.但在get與set方面弱於ArrayList.當然,這些對比都是指數據量很大或者操作很頻繁的情況下的對比。它還實現了 Queue 接口,該接口比List提供了更多的方法,包括 offer(),peek(),poll()等.

注意: 默認情況下ArrayList和Vector的初始容量都是10,所以如果可以預估數據量的話,分配一個較大的初始值屬於最佳實踐,這樣可以減少調整大小的開銷。

 

接下來將Vector 和ArrayList 、 ArrayList和LinkedList進行兩兩對比

ArrayList和Vector

先看一下構造方法

public Vector(int paramInt1, int paramInt2) //使用指定的初始容量和容量增量構造一個空的向量
public Vector(int paramInt) //使用指定初始容量其標准容量增量為零的空向量
public Vector() //使用指定的初始容量為10和容量增量為零的空向量
public Vector(Collection<? extends E> paramCollection) //構造一個包含指定 collection 中的元素的向量
public ArrayList(int paramInt) //構造一個具有指定初始容量的空列表
public ArrayList() //構造一個初始容量為10的空列表
public ArrayList(Collection<? extends E> paramCollection) //構造一個包含指定 collection 的元素的列表
Vector比Arraylist多一個構造方法,就是public Vector(int paramInt1,int paramInt2)這個構造方法,paramInt2就是容量增長,即增長因子,ArrayList中是沒有的。

下面再來看看Arraylist和Vectora的add方法
  public boolean add(E paramE)
  {
    ensureCapacityInternal(this.size + 1);
    this.elementData[(this.size++)] = paramE;
    return true;
  }
private void ensureCapacityInternal(int paramInt) { if (this.elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { paramInt = Math.max(10, paramInt); } ensureExplicitCapacity(paramInt); }
private void ensureExplicitCapacity(int paramInt) { this.modCount += 1; if (paramInt - this.elementData.length > 0) { grow(paramInt); } }
private void grow(int paramInt) { int i = this.elementData.length; int j = i + (i >> 1); if (j - paramInt < 0) { j = paramInt; } if (j - 2147483639 > 0) { j = hugeCapacity(paramInt); } this.elementData = Arrays.copyOf(this.elementData, j); }
 public synchronized boolean add(E paramE)
  {
    this.modCount += 1;
    ensureCapacityHelper(this.elementCount + 1);
    this.elementData[(this.elementCount++)] = paramE;
    return true;
  }

private void ensureCapacityHelper(int paramInt)
  {
    if (paramInt - this.elementData.length > 0) {
      grow(paramInt);
    }
  }

 private void grow(int paramInt)
  {
    int i = this.elementData.length;
    int j = i + (this.capacityIncrement > 0 ? this.capacityIncrement : i);
    if (j - paramInt < 0) {
      j = paramInt;
    }
    if (j - 2147483639 > 0) {
      j = hugeCapacity(paramInt);
    }
    this.elementData = Arrays.copyOf(this.elementData, j);
  }

1、ArrayList在內存不夠時默認是擴展50% + 1個;Vector是當增長因子>0,默認擴展增加一個增長因子,否則默認擴展1倍。

2、Vector的方法加了synchronized, 而ArrayList則沒有。Vector屬於線程安全級別的,但是大多數情況下不使用Vector,因為線程安全需要更大的系統開銷

 

LinkedList和ArrayList的區別

LinkedList和ArrayList的差別主要來自於ArrayList和LinkedList數據結構的不同:

1) 因為ArrayList是基於索引(index)的數據結構,它使用索引在數組中搜索和讀取數據是很快的。ArrayList獲取數據的時間復雜度是O(1),但是要刪除數據卻是開銷很大的,因為這需要重排數組中的所有數據。

2) 相對於ArrayList,LinkedList插入是更快的。因為LinkedList不像ArrayList一樣,不需要改變數組的大小,也不需要在數組裝滿的時候要將所有的數據重新裝入一個新的數組,這是ArrayList最壞的一種情況,時間復雜度是O(n),而LinkedList中插入或刪除的時間復雜度僅為O(1)。ArrayList在插入數據時還需要更新索引(除了插入數組的尾部)。

3) 對於新增和刪除操作add和remove,LinedList比較占優勢,因為ArrayList要移動數據。

4) LinkedList需要更多的內存,因為ArrayList的每個索引的位置是實際的數據,而LinkedList中的每個節點中存儲的是實際的數據和前后節點的位置。

 
Vector      
ArrayList 
LinkedList
實現方式
數組來實現
數組來實現
雙向鏈表
線程安全
方法加了synchronized
 
 
效率
 
查詢快
在尾部添加效率高
在頭部添加 要快很多
刪除數據     要快很多
遍歷
 
for         :1062865 ns
foreach : 2413494 ns
Iterator :1276122 ns
遍歷的時候:選  for
Iterator :1080352 ns
foreach : 2191874 ns
for         :84410739 ns
遍歷的時候:選 Iterator


 


 
 
 
 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM