自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Java中ArrayList和LinkedList區(qū)別

開發(fā) 后端
ArrayList就是傳說中的動態(tài)數(shù)組,用MSDN中的說法,就是Array的復(fù)雜版本,它提供了動態(tài)的增加和減少元素,實(shí)現(xiàn)了ICollection和IList接口,靈活的設(shè)置數(shù)組的大小等好處。

一般大家都知道ArrayListLinkedList的大致區(qū)別:

1.ArrayList是實(shí)現(xiàn)了基于動態(tài)數(shù)組的數(shù)據(jù)結(jié)構(gòu),LinkedList基于鏈表的數(shù)據(jù)結(jié)構(gòu)。

2.對于隨機(jī)訪問get和set,ArrayList覺得優(yōu)于LinkedList,因?yàn)長inkedList要移動指針。

3.對于新增和刪除操作add和remove,LinedList比較占優(yōu)勢,因?yàn)锳rrayList要移動數(shù)據(jù)。

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

一.時間復(fù)雜度

首先一點(diǎn)關(guān)鍵的是,ArrayList的內(nèi)部實(shí)現(xiàn)是基于基礎(chǔ)的對象數(shù)組的,因此,它使用get方法訪問列表中的任意一個元素時 (random access),它的速度要比LinkedList快。LinkedList中的get方法是按照順序從列表的一端開始檢查,直到另外一端。對 LinkedList而言,訪問列表中的某個指定元素沒有更快的方法了。

假設(shè)我們有一個很大的列表,它里面的元素已經(jīng)排好序了,這個列表可能是ArrayList類型的也可能是LinkedList類型的,現(xiàn)在我們對這個列表來進(jìn)行二分查找(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. public static List values;  
  11. static...{  
  12. Integer vals[]=new Integer[N];  
  13. Random r=new Random();  
  14. for(int i=0,currval=0;i<N;i++)...{  
  15. vals=new Integer(currval);  
  16. currval+=r.nextInt(100)+1;  
  17. }  
  18. values=Arrays.asList(vals);  
  19. }  
  20. static long timeList(List lst)...{  
  21. long start=System.currentTimeMillis();  
  22. for(int i=0;i<N;i++)...{  
  23. int index=Collections.binarySearch(lst, values.get(i));  
  24. if(index!=i)  
  25. System.out.println("***錯誤***");  
  26. }  
  27. return System.currentTimeMillis()-start;  
  28. }  
  29. public static void main(String args[])...{  
  30. System.out.println("ArrayList消耗時間:"+timeList(new ArrayList(values)));  
  31. System.out.println("LinkedList消耗時間:"+timeList(new LinkedList(values)));  
  32. }  

 

我得到的輸出 是:ArrayList消耗時間:15

LinkedList消耗時間:2596

這個結(jié)果不是固定的,但是基本上ArrayList的時間要明顯小于LinkedList的時間。因此在這種情況下不宜用LinkedList。二分查找法使用的隨機(jī)訪問(random access)策略,而LinkedList是不支持快速的隨機(jī)訪問的。對一個LinkedList做隨機(jī)訪問所消耗的時間與這個list的大小是成比例的。而相應(yīng)的,在ArrayList中進(jìn)行隨機(jī)訪問所消耗的時間是固定的。

這是否表明ArrayList總是比LinkedList性能要好呢?這并不一定,在某些情況下LinkedList的表現(xiàn)要優(yōu)于ArrayList,有些算法在LinkedList中實(shí)現(xiàn)時效率更高。比方說,利用 Collections.reverse方法對列表進(jìn)行反轉(zhuǎn)時,其性能就要好些。

看這樣一個例子,加入我們有一個列表,要對其進(jìn)行大量的插入和刪除操作,在這種情況下 LinkedList就是一個較好的選擇。請看如下一個極端的例子,我們重復(fù)的在一個列表的開端插入一個元素:

Java代碼

 

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

 

這時我的輸出結(jié)果是:ArrayList耗時:2463

LinkedList耗時:15

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

二.空間復(fù)雜度

在LinkedList中有一個私有的內(nèi)部類,定義如下:

Java代碼

 

  1. private static class Entry {  
  2. Object element;  
  3. Entry next;  
  4. Entry previous;  

 

每個Entry對象 reference列表中的一個元素,同時還有在LinkedList中它的上一個元素和下一個元素。一個有1000個元素的LinkedList對象將有1000個鏈接在一起的Entry對象,每個對象都對應(yīng)于列表中的一個元素。這樣的話,在一個LinkedList結(jié)構(gòu)中將有一個很大的空間開銷,因?yàn)樗鎯@1000個Entity對象的相關(guān)信息。

ArrayList使用一個內(nèi)置的數(shù)組來存儲元素,這個數(shù)組的起始容量是10.當(dāng)數(shù)組需要增長時,新的容量按如下公式獲得:新容量=(舊容量*3)/2+1,也就是說每一次容量大概會增長50%。這就意味著,如果你有一個包含大量元素的ArrayList對象,那么最終將有很大的空間會被浪費(fèi)掉,這個浪費(fèi)是由ArrayList的工作方式本身造成的。如果沒有足夠的空間來存放新的元素,數(shù)組將不得不被重新進(jìn)行分配以便能夠增加新的元素。對數(shù)組進(jìn)行重新分配,將會導(dǎo)致性能急劇下降。如果我們知道一個ArrayList將會有多少個元素,我們可以通過構(gòu)造方法來指定容量。我們還可以通過trimToSize方法在ArrayList分配完畢之后去掉浪費(fèi)掉的空間。

三.總結(jié)

ArrayList和LinkedList在性能上各 有優(yōu)缺點(diǎn),都有各自所適用的地方,總的說來可以描述如下:

1.對ArrayList和LinkedList而言,在列表末尾增加一個元素所花的開銷都是固定的。對 ArrayList而言,主要是在內(nèi)部數(shù)組中增加一項(xiàng),指向所添加的元素,偶爾可能會導(dǎo)致對數(shù)組重新進(jìn)行分配;而對LinkedList而言,這個開銷是統(tǒng)一的,分配一個內(nèi)部Entry對象。

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

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

4.ArrayList的空 間浪費(fèi)主要體現(xiàn)在在list列表的結(jié)尾預(yù)留一定的容量空間,而LinkedList的空間花費(fèi)則體現(xiàn)在它的每一個元素都需要消耗相當(dāng)?shù)目臻g

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

【編輯推薦】

  1. java與云計算
  2. 如何在Java應(yīng)用程序中動態(tài)分配CPU資源
  3. Java源代碼的折行規(guī)則
  4. Java中的四個核心技術(shù)思想
  5. 常見的十四種Java開發(fā)工具的特點(diǎn)
責(zé)任編輯:于鐵 來源: 中國IT實(shí)驗(yàn)室
相關(guān)推薦

2024-10-05 00:00:15

ArrayList性能Java

2019-11-06 16:21:25

ArrayListLinkedListVector

2023-05-16 07:39:15

ArrayList磁盤IO

2022-09-04 18:00:11

ArrayListVector

2021-10-12 16:46:59

ArrayList接口LinkedList

2021-07-08 10:00:59

LinkedLis集合定義

2021-07-11 09:34:45

ArrayListLinkedList

2021-10-09 20:13:03

ArrayListLinkedList java

2023-10-12 08:25:18

Javaequals內(nèi)存

2009-09-01 16:14:05

ArrayList與A

2018-09-29 15:34:34

JavaList接口

2012-03-01 14:04:03

Java

2021-06-10 18:59:41

Java編程語言

2009-06-19 16:46:18

IntegerJava

2021-11-10 15:18:16

JavaGo命令

2011-07-21 17:02:48

JAVA模式框架

2024-11-08 17:15:49

2011-07-10 14:07:59

JAVA

2012-05-29 15:29:14

JavaArrayList

2021-08-04 08:33:59

TypeScriptConst Readonly
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號