ArrayList和LinkedList的大致區(qū)別:
- ArrayList基于動(dòng)態(tài)數(shù)組的數(shù)據(jù)結(jié)構(gòu),LinkedList基于鏈表的數(shù)據(jù)結(jié)構(gòu)。
- 對(duì)于隨機(jī)訪問(wèn)的get和set,ArrayList優(yōu)于LinkedList,因?yàn)長(zhǎng)inkedList要移動(dòng)指針。
- 對(duì)于新增add和刪除remove操作,LinkedList優(yōu)于ArrayList,因?yàn)锳rrayList要移動(dòng)數(shù)據(jù)。
接下來(lái)看下具體的demo,來(lái)比較下兩者的性能。
public class ListDemo {
public static final int N=50000;
public static List values;
public static void main(String args[]){
create();
System.out.println("ArrayList消耗時(shí)間:"+removeTime(new ArrayList(values)));
System.out.println("LinkedList消耗時(shí)間:"+removeTime(new LinkedList(values)));
}
static void create(){
Integer vals[]=new Integer[N];
Random r=new Random();
for(int i=0,currentVal=0;i<N;i++){
vals[i] = currentVal;
currentVal+=r.nextInt(100)+1;
}
values=Arrays.asList(vals);
}
/**
* 比較 get隨機(jī)訪問(wèn) arrayList 優(yōu)于 linkedList
* 二分查找法使用的隨機(jī)訪問(wèn)(random access)策略,而LinkedList是不支持快速的隨機(jī)訪問(wèn)的。對(duì)一個(gè)LinkedList做隨機(jī)訪問(wèn)所消耗的時(shí)間與這個(gè)list的大小是成比例的。而相應(yīng)的,在ArrayList中進(jìn)行隨機(jī)訪問(wèn)所消耗的時(shí)間是固定的
* @param lst
* @return
*/
static long getTime(List lst){
long start=System.currentTimeMillis();
for(int i=0;i<N;i++){
int index=Collections.binarySearch(lst, values.get(i));
if(index!=i)
System.out.println("***錯(cuò)誤***");
}
return System.currentTimeMillis()-start;
}
/**
* 比較 重復(fù)的在一個(gè)列表的開(kāi)端插入一個(gè)元素 linkedList 優(yōu)于 arrayList
* 利用Collections.reverse方法對(duì)列表進(jìn)行反轉(zhuǎn)時(shí),linkedList性能就要好些。
* 當(dāng)一個(gè)元素被加到ArrayList的最開(kāi)端時(shí),所有已經(jīng)存在的元素都會(huì)后移,這就意味著數(shù)據(jù)移動(dòng)和復(fù)制上的開(kāi)銷(xiāo)。相反的,將一個(gè)元素加到LinkedList的最開(kāi)端只是簡(jiǎn)單的未這個(gè)元素分配一個(gè)記錄,然后調(diào)整兩個(gè)連接。在LinkedList的開(kāi)端增加一個(gè)元素的開(kāi)銷(xiāo)是固定的,而在ArrayList的開(kāi)端增加一個(gè)元素的開(kāi)銷(xiāo)是與ArrayList的大小成比例的。
* @param list
* @return
*/
static long addTime(List list){
long start=System.currentTimeMillis();
Object o = new Object();
for(int i=0;i<N;i++){
list.add(0, o);
}
return System.currentTimeMillis()-start;
}
static long removeTime(List list){
long start=System.currentTimeMillis();
Object o = new Object();
for(int i=0;i<N;i++){
list.remove(0);
}
return System.currentTimeMillis()-start;
}
}
從demo數(shù)據(jù)的比較,可以看到arrayList & linkedList在性能上各有優(yōu)缺點(diǎn)。
- 兩者在列表末尾增加一個(gè)元素,所花的開(kāi)銷(xiāo)都是固定的。對(duì)ArrayList而言,會(huì)在內(nèi)部數(shù)組中增加一項(xiàng),指向所添加的元素,偶爾可能會(huì)導(dǎo)致對(duì)數(shù)組重新進(jìn)行分配;對(duì)LinkedList而言,這個(gè)開(kāi)銷(xiāo)是統(tǒng)一的,會(huì)分配一個(gè)內(nèi)部Entry對(duì)象。
- 在ArrayList的中間插入或刪除一個(gè)元素時(shí),這個(gè)列表中剩余的元素都會(huì)被移動(dòng);而在LinkedList的中間插入或刪除一個(gè)元素的開(kāi)銷(xiāo)是固定的。
- LinkedList不支持高效的隨機(jī)元素訪問(wèn)。
- ArrayList的空間浪費(fèi)主要體現(xiàn)在list列表的結(jié)尾會(huì)預(yù)留一定的容量空間,而LinkedList的空間花費(fèi)則體現(xiàn)在它的每一個(gè)單元都需要消耗相當(dāng)?shù)目臻g。