<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 2,  comments - 0,  trackbacks - 0

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

    ArrayList和LinkedList 是兩個集合 類,用于存儲一系列的對象引用(references)。例如我們可以用ArrayList來存儲一系列的String或者Integer。那么 ArrayList和LinkedList在性能上有什么差別呢?什么時候應該用ArrayList什么時候又該用LinkedList呢?


    一.時間復 雜度
    首先一點關鍵的是,ArrayList的內 部實現是基于基礎的對象數組的,因此,它使用get方法訪問列表中的任意一個元素時 (random access),它的速度要比LinkedList快。LinkedList中的get方法是按照順序從列表的一端開始檢查,直到另外一端。對 LinkedList而言,訪問列表中的某個指定元素沒有更快的方法了。
    假設我們有一個很大的列表,它里面的元素已 經排好序了,這個列表可能是ArrayList類型 的也可能是LinkedList類型的,現在我們對這個列表來進行二分查找(binary search),比較列表是ArrayList和LinkedList時的查詢速度,看下面的程序:

    Java代碼
    1. package com.mangocity.test;   
    2. import java.util.LinkedList;   
    3. import java.util.List;   
    4. import java.util.Random;   
    5. import java.util.ArrayList;   
    6. import java.util.Arrays;   
    7. import java.util.Collections;   
    8. public class TestList ...{   
    9.      public static final int N=50000;   
    10.   
    11.      public static List values;   
    12.   
    13.      static...{   
    14.          Integer vals[]=new Integer[N];   
    15.   
    16.          Random r=new Random();   
    17.   
    18.          for(int i=0,currval=0;i<N;i++)...{   
    19.              vals=new Integer(currval);   
    20.              currval+=r.nextInt(100)+1;   
    21.          }   
    22.   
    23.          values=Arrays.asList(vals);   
    24.      }   
    25.   
    26.      static long timeList(List lst)...{   
    27.          long start=System.currentTimeMillis();   
    28.          for(int i=0;i<N;i++)...{   
    29.              int index=Collections.binarySearch(lst, values.get(i));   
    30.              if(index!=i)   
    31.                  System.out.println("***錯誤***");   
    32.          }   
    33.          return System.currentTimeMillis()-start;   
    34.      }   
    35.      public static void main(String args[])...{   
    36.          System.out.println("ArrayList消耗時間:"+timeList(new ArrayList(values)));   
    37.          System.out.println("LinkedList消耗時間:"+timeList(new LinkedList(values)));   
    38.      }   
    39. }   

     
    我得到的輸出 是:ArrayList消耗時間:15
                     LinkedList消耗時間:2596
    這個結果不是固定的,但是基本上 ArrayList的 時間要明顯小于LinkedList的時間。因此在這種情況下不宜用LinkedList。二分查找法使用的隨機訪問(random access)策略,而LinkedList是不支持快速的隨機訪問的。對一個LinkedList做隨機訪問所消耗的時間與這個list的大小是成比例 的。而相應的,在ArrayList中進行隨機訪問所消耗的時間是固定的。
    這是否表明ArrayList總是比 LinkedList性能要好呢?這并不一定,在某些情況 下LinkedList的表現要優于ArrayList,有些算法在LinkedList中實現時效率更高。比方說,利用 Collections.reverse方法對列表進行反轉時,其性能就要好些。
    看這樣一個例子,加入我們有一個列表,要對其進行大量的插入和刪除操作,在這種情況下 LinkedList就是一個較好的選擇。請看如下一個極端的例子,我們重復的在一個列表的開端插入一個元素:

    Java代碼
    1. package com.mangocity.test;   
    2.   
    3. import java.util.*;   
    4. public class ListDemo {   
    5.      static final int N=50000;   
    6.      static long timeList(List list){   
    7.      long start=System.currentTimeMillis();   
    8.      Object o = new Object();   
    9.      for(int i=0;i<N;i++)   
    10.          list.add(0, o);   
    11.      return System.currentTimeMillis()-start;   
    12.      }   
    13.      public static void main(String[] args) {   
    14.          System.out.println("ArrayList耗時:"+timeList(new ArrayList()));   
    15.          System.out.println("LinkedList耗時:"+timeList(new LinkedList()));   
    16.      }   
    17. }   

     這時我的輸出結果是:ArrayList耗時:2463


                               LinkedList耗時:15
    這和前面一個例子的結果截然相反,當一個元 素被加到ArrayList的最開端時,所有已經存在的元素都會后 移,這就意味著數據移動和復制上的開銷。相反的,將一個元素加到LinkedList的最開端只是簡單的未這個元素分配一個記錄,然后調整兩個連接。在 LinkedList的開端增加一個元素的開銷是固定的,而在ArrayList的開端增加一個元素的開銷是與ArrayList的大小成比例的。


    二.空間復 雜度
    在LinkedList中有一個私有的內部類,定義如下:

    Java代碼
    1. private static class Entry {   
    2.          Object element;   
    3.          Entry next;   
    4.          Entry previous;   
    5.      }   

     
    每個Entry對象 reference列表中的一個元素,同時還有在LinkedList中它的上一個元素和下一個元素。一個有1000個元素的LinkedList對象將 有1000個鏈接在一起的Entry對象,每個對象都對應于列表中的一個元素。這樣的話,在一個LinkedList結構中將有一個很大的空間開銷,因為 它要存儲這1000個Entity對象的相關信息。
    ArrayList使用一個內置的數組來存 儲元素,這個數組的起始容量是10.當數組需要增長時,新的容量按 如下公式獲得:新容量=(舊容量*3)/2+1,也就是說每一次容量大概會增長50%。這就意味著,如果你有一個包含大量元素的ArrayList對象, 那么最終將有很大的空間會被浪費掉,這個浪費是由ArrayList的工作方式本身造成的。如果沒有足夠的空間來存放新的元素,數組將不得不被重新進行分 配以便能夠增加新的元素。對數組進行重新分配,將會導致性能急劇下降。如果我們知道一個ArrayList將會有多少個元素,我們可以通過構造方法來指定 容量。我們還可以通過trimToSize方法在ArrayList分配完畢之后去掉浪費掉的空間。


    三.總結
    ArrayList和LinkedList在性能上各 有優缺點,都有各自所適用的地方,總的說來可以描述如下:
    1.對ArrayList和 LinkedList而言,在列表末尾增加一個元素所花的開銷都是固定的。對 ArrayList而言,主要是在內部數組中增加一項,指向所添加的元素,偶爾可能會導致對數組重新進行分配;而對LinkedList而言,這個開銷是 統一的,分配一個內部Entry對象。


    2.在ArrayList的 中間插入或刪除一個元素意味著這個列表中剩余的元素都會被移動;而在LinkedList的中間插入或刪除一個元素的開銷是固定的。


    3.LinkedList不 支持高效的隨機元素訪問。


    4.ArrayList的空 間浪費主要體現在在list列表的結尾預留一定的容量空間,而LinkedList的空間花費則體現在它的每一個元素都需要消耗相當的空間


    可以這樣說:當操作是在一列 數據的后面添加數據而不是在前面或中間,并且需要隨機地訪問其中的元素時,使用ArrayList會提供比較好的性能;當你的操作是在一列數據的前面或中 間添加或刪除數據,并且按照順序訪問其中的元素時,就應該使用LinkedList了。

    posted on 2012-02-08 12:55 wilsonyq 閱讀(136) 評論(0)  編輯  收藏 所屬分類: Java
    主站蜘蛛池模板: 中国亚洲女人69内射少妇| 亚洲欧美日韩一区二区三区在线 | 亚洲区视频在线观看| 亚洲欧美不卡高清在线| 亚洲天堂免费在线| 亚洲国产精品福利片在线观看| 亚洲一区二区三区91| 成人电影在线免费观看| 免费人成视频在线观看视频 | 亚洲国产精品va在线播放| 成人性做爰aaa片免费看| 水蜜桃亚洲一二三四在线| 一边摸一边爽一边叫床免费视频| 成人免费一级毛片在线播放视频| 亚洲国产精品无码久久久不卡 | 免费无码看av的网站| 青青草原精品国产亚洲av| 黄色短视频免费看| 国产精品免费视频网站| 亚洲AV无码乱码麻豆精品国产| 波多野结衣免费在线| 久久久久亚洲AV无码永不| 四虎免费影院ww4164h| 久久久久亚洲精品无码系列| 9420免费高清在线视频| 亚洲欧洲免费视频| 久久狠狠躁免费观看2020| 亚洲中文字幕在线观看| 99久久久国产精品免费蜜臀| 亚洲av无码成h人动漫无遮挡| 中文字幕高清免费不卡视频| 亚洲国产精品不卡毛片a在线| 久久久久亚洲AV无码去区首| 黑人粗长大战亚洲女2021国产精品成人免费视频| 亚洲国产精品成人AV在线| 午夜免费福利在线| 91成人免费观看在线观看| 亚洲成AV人片一区二区| 性色av无码免费一区二区三区| 亚洲熟妇AV一区二区三区浪潮| 成人在线视频免费|