java List系(ArrayList,LinkedList,Vector)的比較__java

來源:互聯網
上載者:User


主要是複習一下以前學過的知識,也許還能協助一下剛學習java的新手^-^

所以我也開通了自己的部落格


言歸正傳,網上講java List的部落格也不少,但是我最近看了一本《資料結構與演算法分析 java語言描述》,裡面對list實作類別的講解還不錯,也讓我多他們有了更好一點的理解,所以我覺得我還是從這裡開始吧,也把自己這方面的知識再鞏固一下^-^.


我以前的理解: ArrayList:提供了List可增長數組的實現,對於隨機的get,set調用花費常數時間(即效能更好),但是其對於非末端的add,remove往往花費對數時間(效能比較差)。 Vector:與ArrayList基本一樣,但其是安全執行緒的,所以犧牲一部分效能比ArrayList略差 LinkedList:提供了List的雙鏈表實現,對於隨機add,remove往往開銷更小,但不易做索引,故隨機get,set往往效能更差
實際環境操作: 環境:jdk1.8,Eclipse,以下測試都具有一定的片面性,但我覺得大致能體現一些東西,如有錯誤,希望指教^-^ 1.尾部add操作:

public static void main(String[] args) {ArrayList<Integer> list1 = new ArrayList<>();LinkedList<Integer> list2 = new LinkedList<>();Vector<Integer> list3 = new Vector<>();new Thread(new Runnable() {public void run() {makeList1(list1, 30000);}}).start();new Thread(new Runnable() {public void run() {makeList1(list2, 30000);}}).start();new Thread(new Runnable() {public void run() {makeList1(list3, 30000);}}).start();}


public static List<Integer> makeList1(List<Integer> oo , int n) {oo.clear();Long begin = System.currentTimeMillis();for(int i = 0 ; i < n ; i++) {oo.add(i);//1oo.add(0 , i);//2oo.add(i/2 , i);//3}System.out.println(oo.getClass().getName() + ":我是添加方法:" + (System.currentTimeMillis() - begin));return oo;}


結果:我發現若在main裡面逐一調用,先後順序對結果有一定影響,故使用多線程調用保證公平 第一次運行: 第二次運行: 第三次運行: java.util.ArrayList:我是添加方法:32 java.util.ArrayList:我是添加方法:43 java.util.LinkedList:我是添加方法:43
java.util.Vector:我是添加方法:32 java.util.Vector:我是添加方法:43 java.util.Vector:我是添加方法:37
java.util.LinkedList:我是添加方法:29 java.util.LinkedList:我是添加方法:43 java.util.LinkedList:我是添加方法:40
結論:可以看出,對於尾部add操作,三種列表的效能幾乎沒有相同,也可改變n大小,結果消耗時間幾乎為線性增長(為o(N))。當n很大時不能保持o(N),我個人認為是我機器的原因。
2.頭部add操作:將1操作中的makeList1方法中1,3注釋,消除2的注釋
n=2000運行: n=20000運行: n=200000運行: java.util.ArrayList:我是添加方法:2 java.util.Array List:我是添加方法:49 java.util.ArrayList:我是添加方法:5274
java.util.LinkedList:我是添加方法:1 java.util.LinkedList:我是添加方法:5 java.util.LinkedList:我是添加方法:25
java.util.Vector:我是添加方法:3 java.util.Vector:我是添加方法:47 java.util.Vector:我是添加方法:5285

結論:對於頭部操作LinkedList消耗時間依然保持線性增長(o(N)),但ArrayList,Vector幾乎已(o(N^2))增長。
3.中部操作:將makeList1方法中1,2注釋,消除3的注釋
n=2000運行: n=20000運行: n=80000運行: java.util.ArrayList:我是添加方法:1 java.util.ArrayList:我是添加方法:33 java.util.ArrayList:我是添加方法:667
java.util.Vector:我是添加方法:1 java.util.Vector:我是添加方法:23 java.util.Vector:我是添加方法:670
java.util.LinkedList:我是添加方法:5 java.util.LinkedList:我是添加方法:294 java.util.LinkedList:我是添加方法:27950

結論:這個結果讓我有一些意外,原因應該是在中部add時LinkedList一樣要去遍曆尋找index,而ArrayList只需把一般元素往後移動。故LinkedList只在前端時效能操作ArrayList;

4.get操作:
<pre name="code" class="java">public static void getList1(List<Integer> oo){int total = 0;Long begin = System.currentTimeMillis();for(int i = 0 ; i < oo.size() ; i++) {total += oo.get(i);
}System.out.println(oo.getClass().getName() + ":get已耗用時間:" + (System.currentTimeMillis() - begin) +"結果" + total);}
getList1(makeList1(list2, 20000));//run方法裡面的函數改為這個

 
 
public static void getList1(List<Integer> oo){int total = 0;Iterator<Integer> itr = oo.iterator();Long begin = System.currentTimeMillis();while(itr.hasNext()){total += itr.next();}System.out.println(oo.getClass().getName() + ":get已耗用時間:" + (System.currentTimeMillis() - begin) +"結果" + total);}


n=20000運行: n=60000運行: java.util.ArrayList:我是添加方法:2 java.util.ArrayList:我是添加方法:10
java.util.ArrayList:get已耗用時間:2結果199990000 java.util.ArrayList:get已耗用時間:2結果1799970000
java.util.LinkedList:我是添加方法:5 java.util.LinkedList:我是添加方法:6
java.util.LinkedList:get已耗用時間:176結果199990000 java.util.LinkedList:get已耗用時間:1534結果1799970000
java.util.Vector:我是添加方法:3 java.util.Vector:我是添加方法:8
java.util.Vector:get已耗用時間:2結果199990000 java.util.Vector:get已耗用時間:6結果1799970000


當使用下面的getList1方法時,三者效能幾乎誤差,有興趣的可以試試 結論:ArrayList還有Vector花費時間基本保持線性,LinkedList呈o(N^2)增長,set操作與個體操作結果基本一致。
5.遍曆remove操作:
public static void removeList1(List<Integer> oo) {Iterator<Integer> itr = oo.iterator();Long begin = System.currentTimeMillis();while(itr.hasNext()){if(itr.next() % 3 == 0) itr.remove();}System.out.println(oo.getClass().getName() + "我是刪除方法:" + (System.currentTimeMillis() - begin));}
</pre><pre name="code" class="java">removeList1(makeList1(list1, 300000));//將run方法內容改成這樣


n=60000運行: n=600000運行: java.util.LinkedList我是刪除方法:9 java.util.LinkedList我是刪除方法:17
java.util.ArrayList我是刪除方法:134 java.util.ArrayList我是刪除方法:3797
java.util.Vector我是刪除方法:139 java.util.Vector我是刪除方法:3802

結論:LinkedList操作時間保持線性,Vector,ArrayList呈O(N^2)
6.隨機remove操作:
public static void removeList1(List<Integer> oo) {int n = oo.size()/2 ;Long begin = System.currentTimeMillis();for(int i = n; n > 0 ; n-- ){oo.remove(i);}System.out.println(oo.getClass().getName() + "我是刪除方法:" + (System.currentTimeMillis() - begin));}

n=3000運行: n=9000運行: java.util.ArrayList我是刪除方法:1 java.util.ArrayList我是刪除方法:4
java.util.Vector我是刪除方法:1 java.util.Vector我是刪除方法:3
java.util.LinkedList我是刪除方法:5 java.util.LinkedList我是刪除方法:20

結論:此時LinkedList效能並不如ArrayList,Vector 總結: 對比以上資料,發現:只要是在進行隨機的操作時,LinkedList效能總是不如ArrayList,Vector。而在非隨機(Iterator遍曆的情況下)LinkedList在進行增加,刪除效能效能總體是優於ArrayList,Vector 故,我認為在你要時常進行隨機操作的資料時,你應該用ArrayList或者Vector。在不需要時常隨時操作的時候用LinkedList

發現一個問題,為什麼在我的實踐中vector好多時候並沒有比ArrayList效能差。。。難道是因為我用了多線程。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.