ArrayList和LinkedList的區別

好像這個問題是java筆試必有的一個問題,

一般大家都知道ArrayList和LinkedList的大致區別:
1.ArrayList是實現了基於動態數組的數據結構,LinkedList基於鏈表的數據結構。
2.對於隨機訪問get和set,ArrayList覺得優於LinkedList,因爲LinkedList要移動指針。
3.對於新增和刪除操作add和remove,LinedList比較佔優勢,因爲ArrayList要移動數據。

由於sun的開源所以我們可以從代碼的角度來看他們兩個之間的區別;

先從構造函數說起

ArrayList 的默認構造函數

  1. publicArrayList(){
  2. this(10);
  3. }

這個10是什麼意思呢?再看看帶參數的構造函數就明白了

  1. publicArrayList(intinitialCapacity){
  2. super();
  3. if(initialCapacity<0)
  4. thrownewIllegalArgumentException("IllegalCapacity:"+
  5. initialCapacity);
  6. this.elementData=newObject[initialCapacity];
  7. }

原來是是爲ArrayList 分配了10個Object的數組存儲空間。

下面看看LinkedList的構造函數

  1. publicLinkedList(){
  2. header.next=header.previous=header;
  3. }

把鏈表的指針全部歸零,從上面的代碼可以看出LinkedList是個雙向的鏈表。

下面再來看看兩者的get 和add方法有上面區別

首先來看ArrayList add方法

  1. publicbooleanadd(Ee){
  2. ensureCapacity(size+1);//IncrementsmodCount!!
  3. elementData[size++]=e;
  4. returntrue;
  5. }

ensureCapacity 這個函數是什麼意思呢?看看就知道了

  1. publicvoidensureCapacity(intminCapacity){
  2. modCount++;
  3. intoldCapacity=elementData.length;
  4. if(minCapacity>oldCapacity){
  5. ObjectoldData[]=elementData;
  6. intnewCapacity=(oldCapacity*3)/2+1;
  7. if(newCapacity<minCapacity)
  8. newCapacity=minCapacity;
  9. //minCapacityisusuallyclosetosize,sothisisawin:
  10. elementData=Arrays.copyOf(elementData,newCapacity);
  11. }
  12. }

原來這個確保ArrayList 存儲空間自動增長的,看了代碼就知道原來ArrayList 初始化存儲空間的大小是10 然後以後以1.5+1的級數增長,在這個過程中先new 原來空間的1.5倍+1的新空間,然後把原來的數據拷貝到新的空間,所以說ArrayList 的添加數據的性能低於LinkedList,原來原因出在此處,那麼以後就可以在new ArrayList 的時候,根據實際數據的多少,大概的指定一下ArrayList 的初始化大小,這樣避免的多次數據拷貝,提高了系統性能,哈哈又學到了優化的一招。

接下來繼續看LinkedList的add方法

  1. publicbooleanadd(Ee){
  2. addBefore(e,header);
  3. returntrue;
  4. }
  5. privateEntry<E>addBefore(Ee,Entry<E>entry){
  6. Entry<E>newEntry=newEntry<E>(e,entry,entry.previous);
  7. newEntry.previous.next=newEntry;
  8. newEntry.next.previous=newEntry;
  9. size++;
  10. modCount++;
  11. returnnewEntry;
  12. }

就是雙向鏈表的添加操作,這是數據結構裏面的必修煉的功力之一,在添加的時候只要修改一下指針就ok了,沒有ArrayList 的增長空間拷貝數據的步驟,所以總體上看來在add的時候,LinkedList比ArrayList 快。

下面來看看ArrayList 的get方法

  1. publicEget(intindex){
  2. RangeCheck(index);
  3. return(E)elementData[index];
  4. }

RangeCheck 檢測訪問是否越界,然後根據索引下標直接返回值,果然快。

再來看看LinkedList的get方法

  1. publicEget(intindex){
  2. returnentry(index).element;
  3. }
  4. privateEntry<E>entry(intindex){
  5. if(index<0||index>=size)
  6. thrownewIndexOutOfBoundsException("Index:"+index+
  7. ",Size:"+size);
  8. Entry<E>e=header;
  9. if(index<(size>>1)){
  10. for(inti=0;i<=index;i++)
  11. e=e.next;
  12. }else{
  13. for(inti=size;i>index;i--)
  14. e=e.previous;
  15. }
  16. returne;
  17. }

一個一個去找是比較的慢,不過還是優化了,如果要找的數小於等於size的一半就從頭往後找,要是大於size的一半就從後往前找,LinkedList的get和ArrayList 比起來確實慢了很多。

發佈了0 篇原創文章 · 獲贊 0 · 訪問量 2779
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章