您的位置:首页 > 其它

ArryList vs LinkedList

2014-03-27 11:26 92 查看
references:
http://www.javaperformancetuning.com/articles/randomaccess.shtmlhttp://stackoverflow.com/questions/322715/when-to-use-linkedlist-over-arraylist
LinkedListandArrayListaretwodifferentimplementationsoftheListinterface.LinkedListimplementsitwithadoubly-linkedlist.ArrayListimplementsitwithadynamicallyresizingarray.

Aswithstandardlinkedlistandarrayoperations,thevariousmethodswillhavedifferentalgorithmicruntimes.

For
LinkedList<E>


get(intindex)
isO(n)

add(Eelement)
isO(1)

add(intindex,Eelement)
isO(n)

remove(intindex)
isO(n)

Iterator.remove()
isO(1)<---mainbenefitof
LinkedList<E>


ListIterator.add(Eelement)
isO(1)<---mainbenefitof
LinkedList<E>


For
ArrayList<E>


get(intindex)
isO(1)<---mainbenefitof
ArrayList<E>


add(Eelement)
isO(1)amortized,butO(n)worst-casesincethearraymustberesizedandcopied

add(intindex,Eelement)
isO(n-index)amortized,butO(n)worst-case(asabove)

remove(intindex)
isO(n-index)(i.e.removinglastisO(1))

Iterator.remove()
isO(n-index)

ListIterator.add(Eelement)
isO(n-index)

LinkedList<E>
allowsforconstant-timeinsertionsorremovalsusingiterators,butonlysequentialaccessofelements.Inotherwords,youcanwalkthelistforwardsorbackwards,butfindingapositioninthelisttakestimeproportionaltothesizeofthelist.

ArrayList<E>
,ontheotherhand,allowfastrandomreadaccess,soyoucangrabanyelementinconstanttime.Butaddingorremovingfromanywherebuttheendrequiresshiftingallthelatterelementsover,eithertomakeanopeningorfillthegap.Also,ifyouaddmoreelementsthanthecapacityoftheunderlyingarray,anewarray(twicethesize)isallocated,andtheoldarrayiscopiedtothenewone,soaddingtoanArrayListisO(n)intheworstcasebutconstantonaverage.

Sodependingontheoperationsyouintendtodo,youshouldchoosetheimplementationsaccordingly.IteratingovereitherkindofListispracticallyequallycheap.(Iteratingoveran
ArrayList
istechnicallyfaster,butunlessyou'redoingsomethingreallyperformance-sensitive,youshouldn'tworryaboutthis--they'rebothconstants.)

Themainbenefitsofusinga
LinkedList
arisewhenyoure-useexistingiteratorstoinsertandremoveelements.TheseoperationscanthenbedoneinO(1)bychangingthelistlocallyonly.Inanarraylist,theremainderofthearrayneedstobemoved(i.e.copied).Ontheotherside,seekingina
LinkedList
meansfollowingthelinksinO(n),whereasinan
ArrayList
thedesiredpositioncanbecomputedmathematicallyandaccessedinO(1).

Also,ifyouhavelargelists,keepinmindthatmemoryusageisalsodifferent.EachelementofaLinkedListhasmoreoverheadsincepointerstothenextandpreviouselementsarealsostored.ArrayListsdon'thavethisoverhead.However,ArrayListstakeupasmuchmemoryasisallocatedforthecapacity,regardlessofwhetherelementshaveactuallybeenadded.

ThedefaultinitialcapacityofanArrayListisprettysmall(10fromJava1.4-1.7).Butsincetheunderlyingimplementationisanarray,thearraymustberesizedifyouaddalotofelements.Toavoidthehighcostofresizingwhenyouknowyou'regoingtoaddalotofelements,constructtheArrayListwithahigherinitialcapacity.

It'sworthnotingthatVectoralsoimplementstheListinterfaceandisalmostidenticaltoArrayList.ThedifferenceisthatVectorissynchronized,soitisthread-safe.Becauseofthis,itisalsoslightlyslowerthanArrayList.SoasfarasIunderstand,mostJavaprogrammersavoidVectorinfavorofArrayListsincetheywillprobablysynchronizeexplicitlyanywayiftheycareaboutthat.

Thusfar,nobodyseemstohaveaddressedthememoryfootprintofeachoftheselistsbesidesthegeneralconsensusthata
LinkedList
is"lotsmore"thanan
ArrayList
soIdidsomenumbercrunchingtodemonstrateexactlyhowmuchbothliststakeupforNnullreferences.

Sincereferencesareeither32or64bits(evenwhennull)ontheirrelativesystems,Ihaveincluded4setsofdatafor32and64bit
LinkedLists
and
ArrayLists
.

Note:Thesizesshownforthe
ArrayList
linesarefortrimmedlists-Inpractice,thecapacityofthebackingarrayinan
ArrayList
isgenerallylargerthanitscurrentelementcount.

Note2:(thanksBeeOnRope)AsCompressedOopsisdefaultnowfrommidJDK6andup,thevaluesbelowfor64-bitmachineswillbasicallymatchtheir32-bitcounterparts,unlessofcourseyouspecificallyturnitoff.



Theresultclearlyshowsthat
LinkedList
isawholelotmorethan
ArrayList
,especiallywithaveryhighelementcount.Ifmemoryisafactor,steerclearof
LinkedLists
.

TheformulasIusedfollow,letmeknowifIhavedoneanythingwrongandIwillfixitup.'b'iseither4or8for32or64bitsystems,and'n'isthenumberofelements.Notethereasonforthemodsisbecauseallobjectsinjavawilltakeupamultipleof8bytesspaceregardlessofwhetheritisallusedornot.

ArrayList
:

ArrayListobjectheader+sizeinteger+modCountinteger+arrayreference+(arrayojectheader+b*n)+MOD(arrayoject,8)+MOD(ArrayListobject,8)==8+4+4+b+(12+b*n)+MOD(12+b*n,8)+MOD(8+4+4+b+(12+b*n)+MOD(12+b*n,8),8)

LinkedList
:

LinkedListobjectheader+sizeinteger+modCountinteger+referencetoheader+referencetofooter+(nodeobjectoverhead+referencetopreviouselement+referencetonextelement+referencetoelement)*n)+MOD(nodeobject,8)*n+MOD(LinkedListobject,8)==8+4+4+2*b+(8+3*b)*n+MOD(8+3*b,8)*n+MOD(8+4+4+2*b+(8+3*b)*n+MOD(8+3*b,8)*n,8)



Testing:

ArrayListLinkedListAddAll(Insert)101,167192623,29291Add(Insert-Sequentially)152,46840966,62216Add(insert-randomly)3652729193

remove(Delete)20,56,909520,45,4904

contains(Search)186,15,704189,64,981


importorg.junit.Assert;
importorg.junit.Test;

importjava.util.*;

publicclassArrayListVsLinkedList{
privatestaticfinalintMAX=500000;
String[]strings=maxArray();

//////////////ADDALL////////////////////////////////////////
@Test
publicvoidarrayListAddAll(){
Watchwatch=newWatch();
List<String>stringList=Arrays.asList(strings);
List<String>arrayList=newArrayList<String>(MAX);

watch.start();
arrayList.addAll(stringList);
watch.totalTime("ArrayListaddAll()=");//101,16719Nanoseconds
}

@Test
publicvoidlinkedListAddAll()throwsException{
Watchwatch=newWatch();
List<String>stringList=Arrays.asList(strings);

watch.start();
List<String>linkedList=newLinkedList<String>();
linkedList.addAll(stringList);
watch.totalTime("LinkedListaddAll()=");//2623,29291Nanoseconds
}

//Note:ArrayListis26timefasterherethanLinkedListforaddAll()

/////////////////INSERT/////////////////////////////////////////////
@Test
publicvoidarrayListAdd(){
Watchwatch=newWatch();
List<String>arrayList=newArrayList<String>(MAX);

watch.start();
for(Stringstring:strings)
arrayList.add(string);
watch.totalTime("ArrayListadd()=");//152,46840Nanoseconds
}

@Test
publicvoidlinkedListAdd(){
Watchwatch=newWatch();

List<String>linkedList=newLinkedList<String>();
watch.start();
for(Stringstring:strings)
linkedList.add(string);
watch.totalTime("LinkedListadd()=");//966,62216Nanoseconds
}

//Note:ArrayListis9timesfasterthanLinkedListforaddsequentially

///////////////////INSERTINBETWEEN///////////////////////////////////////

@Test
publicvoidarrayListInsertOne(){
Watchwatch=newWatch();
List<String>stringList=Arrays.asList(strings);
List<String>arrayList=newArrayList<String>(MAX+MAX/10);
arrayList.addAll(stringList);

StringinsertString0=getString(true,MAX/2+10);
StringinsertString1=getString(true,MAX/2+20);
StringinsertString2=getString(true,MAX/2+30);
StringinsertString3=getString(true,MAX/2+40);

watch.start();

arrayList.add(insertString0);
arrayList.add(insertString1);
arrayList.add(insertString2);
arrayList.add(insertString3);

watch.totalTime("ArrayListadd()=");//36527
}

@Test
publicvoidlinkedListInsertOne(){
Watchwatch=newWatch();
List<String>stringList=Arrays.asList(strings);
List<String>linkedList=newLinkedList<String>();
linkedList.addAll(stringList);

StringinsertString0=getString(true,MAX/2+10);
StringinsertString1=getString(true,MAX/2+20);
StringinsertString2=getString(true,MAX/2+30);
StringinsertString3=getString(true,MAX/2+40);

watch.start();

linkedList.add(insertString0);
linkedList.add(insertString1);
linkedList.add(insertString2);
linkedList.add(insertString3);

watch.totalTime("LinkedListadd=");//29193
}

//Note:LinkedListis3000nanosecondfasterthanArrayListforinsertrandomly.

//////////////////DELETE//////////////////////////////////////////////////////
@Test
publicvoidarrayListRemove()throwsException{
Watchwatch=newWatch();
List<String>stringList=Arrays.asList(strings);
List<String>arrayList=newArrayList<String>(MAX);

arrayList.addAll(stringList);
StringsearchString0=getString(true,MAX/2+10);
StringsearchString1=getString(true,MAX/2+20);

watch.start();
arrayList.remove(searchString0);
arrayList.remove(searchString1);
watch.totalTime("ArrayListremove()=");//20,56,9095Nanoseconds
}

@Test
publicvoidlinkedListRemove()throwsException{
Watchwatch=newWatch();
List<String>linkedList=newLinkedList<String>();
linkedList.addAll(Arrays.asList(strings));

StringsearchString0=getString(true,MAX/2+10);
StringsearchString1=getString(true,MAX/2+20);

watch.start();
linkedList.remove(searchString0);
linkedList.remove(searchString1);
watch.totalTime("LinkedListremove=");//20,45,4904Nanoseconds
}

//Note:LinkedListis10millisecondfasterthanArrayListwhileremovingitem.

/////////////////////SEARCH///////////////////////////////////////////
@Test
publicvoidarrayListSearch()throwsException{
Watchwatch=newWatch();
List<String>stringList=Arrays.asList(strings);
List<String>arrayList=newArrayList<String>(MAX);

arrayList.addAll(stringList);
StringsearchString0=getString(true,MAX/2+10);
StringsearchString1=getString(true,MAX/2+20);

watch.start();
arrayList.contains(searchString0);
arrayList.contains(searchString1);
watch.totalTime("ArrayListaddAll()time=");//186,15,704
}

@Test
publicvoidlinkedListSearch()throwsException{
Watchwatch=newWatch();
List<String>linkedList=newLinkedList<String>();
linkedList.addAll(Arrays.asList(strings));

StringsearchString0=getString(true,MAX/2+10);
StringsearchString1=getString(true,MAX/2+20);

watch.start();
linkedList.contains(searchString0);
linkedList.contains(searchString1);
watch.totalTime("LinkedListaddAll()time=");//189,64,981
}

//Note:LinkedListis500MillisecondsfasterthanArrayList

classWatch{
privatelongstartTime;
privatelongendTime;

publicvoidstart(){
startTime=System.nanoTime();
}

privatevoidstop(){
endTime=System.nanoTime();
}

publicvoidtotalTime(Strings){
stop();
System.out.println(s+(endTime-startTime));
}
}

privateString[]maxArray(){
String[]strings=newString[MAX];
Booleanresult=Boolean.TRUE;
for(inti=0;i<MAX;i++){
strings[i]=getString(result,i);
result=!result;
}
returnstrings;
}

privateStringgetString(Booleanresult,inti){
returnString.valueOf(result)+i+String.valueOf(!result);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: