Java數據結構之LinkedList、ArrayList的效率分析

前言:

     在咱們日常開發中不免會用到List集合來存儲數據,通常都會選擇ArrayList和LinkedList,之前只是大體知道ArrayList查詢效率高LinkedList插入刪除效率高,今天來實測一下。java

先了解一下List     

  List列表類,順序存儲任何對象(順序不變),可重複。數組

  List是繼承於Collection的接口,不能實例化。實例化能夠用:緩存

  • ArrayList(實現動態數組),查詢快(隨意訪問或順序訪問),增刪慢。總體清空快,線程不一樣步(非線程安全)。數組長度是可變的百分之五十延長
  • LinkedList(實現鏈表),查詢慢,增刪快。
  • Vector(實現動態數組),都慢,被ArrayList替代。長度任意延長。線程安全(同步的類,函數都是synchronized)
  • Stack(實現堆棧)繼承於Vector,先進後出。

    List基本操做安全

  • 插入:add()
  • 查找:get()
  • 刪除:remove(int index)
  • 修改:set()
  • 清空表:clear()
  • 遍歷:用Iterator迭代器遍歷每一個元素

ArrayList、LinkedList性能對比

爲了很好的對比效率,直接寫個測試程序看下運行結果數據結構

模擬5w條數據指定插入第一位,而後查詢所有,循環刪除第一位,下面是測試ArrayList函數函數

private void testArrayList(){
        ArrayList<String> list=new ArrayList<>();
        int maxTestCount=50000;

        //測試添加
        long start =System.currentTimeMillis();

        for(int i =0;i<maxTestCount;i++){
            list.add(0,String.valueOf(i));
        }

        long end =System.currentTimeMillis();

        Log.e(TAG,"ArrayList add cost time :"+(end-start));

        //測試查詢
        start =System.currentTimeMillis();

        for(int i =0;i<maxTestCount;i++){
            list.get(i);
        }

        end =System.currentTimeMillis();

        Log.e(TAG,"ArrayList get cost time :"+(end-start));

        //測試查詢
        start =System.currentTimeMillis();

        for(int i =maxTestCount;i>0;i--){
            list.remove(0);
        }

        end =System.currentTimeMillis();

        Log.e(TAG,"ArrayList remove cost time :"+(end-start));

    }

測試LinkedList函數性能

private void testLinkedList(){
        LinkedList<String> list=new LinkedList<>();
        int maxTestCount=50000;

        //測試添加
        long start =System.currentTimeMillis();

        for(int i =0;i<maxTestCount;i++){
            list.add(0,String.valueOf(i));
        }

        long end =System.currentTimeMillis();

        Log.e(TAG,"LinkedList add cost time :"+(end-start));

        //測試查詢
        start =System.currentTimeMillis();

        for(int i =0;i<maxTestCount;i++){
            list.get(i);
        }

        end =System.currentTimeMillis();

        Log.e(TAG,"LinkedList get cost time :"+(end-start));


        //測試查詢
        start =System.currentTimeMillis();

        for(int i =maxTestCount;i>0;i--){
            list.remove(0);
        }

        end =System.currentTimeMillis();

        Log.e(TAG,"LinkedList remove cost time :"+(end-start));

    }

前後調用兩個函數,看下運行結果測試

經過上面的運行結果能夠大體得出如下結論:spa

  • ArrayList插入、刪除效率明顯低於LinkedList
  • ArrayList查詢效率遠遠高於LinkedList

經過上面的結構是否是就能夠認爲插入刪除頻繁選擇LinkedList,追求查詢效率就選擇ArrayList呢,咱們先來分析一下效率差異的緣由,這個就跟數據結構有關係了,能夠參考一些數據結構中鏈表的知識,arraylist 順序表,用數組的方式實現。想一想數組要查詢那個元素只給出其下標便可,因此才說arraylist隨機訪問多的場景比較合適。可是若是刪除某個元素好比第 i 個元素,則要將 i 以後的元素都向前移一位以保證順序表的正確,增長也是同樣,要移動多個元素。要屢次刪除增長的話是很低效的。而LinkedList是雙向鏈表,注意是鏈表。要查詢只能頭結點開始逐步查詢,沒有什麼給出下標便可直接查詢的便利,須要遍歷。可是,若是要增長後刪除一個元素的話,只須要改變其先後元素的指向便可,不須要像arraylist那樣總體移動,因此才說多用於增刪多的場合。線程

很感謝博友的建議與幫助,因爲LinkedList查詢只能從頭結點開始逐步查詢的,可使用 iterator 的方式,就不用每次都從頭結點開始訪問,由於它會緩存當前結點的先後結點。實測查詢效率與ArrayList沒有太大差異

LinkedList<String> list = new LinkedList<>();
Iterator<String> it = list.iterator();
 while(it.hasNext()){
      String s = it.next();
    }

List其餘知識擴展

Vector 是矢量隊列,和ArrayList同樣,它也是一個動態數組,由數組實現。可是ArrayList是非線程安全的,而Vector是線程安全的。
Stack 是棧,它繼承於Vector。它的特性是:先進後出(FILO, First In Last Out)。

總結:

   經過運行結果和查閱資料基本上驗證了ArrayList和LinkedList效率問題,有助於在之後的開發中根據實際場景選擇合適的技術方案。

相關文章
相關標籤/搜索