ArrayList和LinkedList的几种循环遍历方式及性能对比分析.docx

上传人:b****4 文档编号:5063079 上传时间:2022-12-12 格式:DOCX 页数:13 大小:24.15KB
下载 相关 举报
ArrayList和LinkedList的几种循环遍历方式及性能对比分析.docx_第1页
第1页 / 共13页
ArrayList和LinkedList的几种循环遍历方式及性能对比分析.docx_第2页
第2页 / 共13页
ArrayList和LinkedList的几种循环遍历方式及性能对比分析.docx_第3页
第3页 / 共13页
ArrayList和LinkedList的几种循环遍历方式及性能对比分析.docx_第4页
第4页 / 共13页
ArrayList和LinkedList的几种循环遍历方式及性能对比分析.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

ArrayList和LinkedList的几种循环遍历方式及性能对比分析.docx

《ArrayList和LinkedList的几种循环遍历方式及性能对比分析.docx》由会员分享,可在线阅读,更多相关《ArrayList和LinkedList的几种循环遍历方式及性能对比分析.docx(13页珍藏版)》请在冰豆网上搜索。

ArrayList和LinkedList的几种循环遍历方式及性能对比分析.docx

ArrayList和LinkedList的几种循环遍历方式及性能对比分析

主要介绍ArrayList和LinkedList这两种list的五种循环遍历方式,各种方式的性能测试比照,根据ArrayList和LinkedList的源码实现分析性能结果,总结结论。

通过本文你可以了解

(1)List的五种遍历方式及各自性能

(2)foreach及Iterator的实现(3)加深对ArrayList和LinkedList实现的了解。

阅读本文前希望你已经了解ArrayList顺序存储和LinkedList链式的构造,本文不对此进展介绍。

相关:

HashMap循环遍历方式及其性能比照

 

1.List的五种遍历方式

下面只是简单介绍各种遍历例如(以ArrayList为例),各自优劣会在本文后面进展分析给出结论。

(1)foreach循环

Java

1

2

3

4

Listlist=newArrayList();

for(Integerj:

list){

//usej

}

 

(2)显示调用集合迭代器

Java

1

2

3

4

Listlist=newArrayList();

for(Iteratoriterator=list.iterator();iterator.hasNext();){

iterator.next();

}

Java

1

2

3

4

5

Listlist=newArrayList();

Iteratoriterator=list.iterator();

while(iterator.hasNext()){

iterator.next();

}

 

(3)下标递增循环,终止条件为每次调用size()函数比拟判断

Java

1

2

3

4

Listlist=newArrayList();

for(intj=0;j

list.get(j);

}

 

(4)下标递增循环,终止条件为和等于size()的临时变量比拟判断

Java

1

2

3

4

5

Listlist=newArrayList();

intsize=list.size();

for(intj=0;j

list.get(j);

}

 

(5)下标递减循环

Java

1

2

3

4

Listlist=newArrayList();

for(intj=list.size()-1;j>=0;j--){

list.get(j);

}

在测试前大家可以根据对ArrayList和LinkedList数据构造及Iterator的了解,想想上面五种遍历方式哪个性能更优。

 

2、List五种遍历方式的性能测试及比照

以下是性能测试代码,会输出不同数量级大小的ArrayList和LinkedList各种遍历方式所花费的时间。

ArrayList和LinkedList循环性能比照测试代码

PS:

如果运行报异常inthread“main〞java.lang.OutOfMemoryError:

Javaheapspace,请将main函数里面listsize的大小减小。

其中getArrayLists函数会返回不同size的ArrayList,getLinkedLists函数会返回不同size的LinkedList。

loopListpare函数会分别用上面的遍历方式1-5去遍历每一个list数组(包含不同大小list)中的list。

print开头函数为输出辅助函数。

 

测试环境为Windows732位系统3.2G双核CPU4G内存,Java7,Eclipse-Xms512m-Xmx512m

最终测试结果如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

pareloopperformanceofArrayList

-----------------------------------------------------------------------

listsize              |10,000    |100,000  |1,000,000|10,000,000

-----------------------------------------------------------------------

foreach              |1ms      |3ms      |14ms    |152ms    

-----------------------------------------------------------------------

foriterator          |0ms      |1ms      |12ms    |114ms    

-----------------------------------------------------------------------

forlist.size()        |1ms      |1ms      |13ms    |128ms    

-----------------------------------------------------------------------

forsize=list.size()|0ms      |0ms      |6ms      |62ms    

-----------------------------------------------------------------------

forj--                |0ms      |1ms      |6ms      |63ms    

-----------------------------------------------------------------------

 

pareloopperformanceofLinkedList

-----------------------------------------------------------------------

listsize              |100      |1,000    |10,000    |100,000  

-----------------------------------------------------------------------

foreach              |0ms      |1ms      |1ms      |2ms      

-----------------------------------------------------------------------

foriterator          |0ms      |0ms      |0ms      |2ms      

-----------------------------------------------------------------------

forlist.size()        |0ms      |1ms      |73ms    |7972ms  

-----------------------------------------------------------------------

forsize=list.size()|0ms      |0ms      |67ms    |8216ms  

-----------------------------------------------------------------------

forj--                |0ms      |1ms      |67ms    |8277ms  

-----------------------------------------------------------------------

第一X表为ArrayList比照结果,第二X表为LinkedList比照结果。

表横向为同一遍历方式不同大小list遍历的时间消耗,纵向为同一list不同遍历方式遍历的时间消耗。

PS:

由于首次遍历List会稍微多耗时一点,foreach的结果稍微有点偏差,将测试代码中的几个Type顺序调换会发现,foreach耗时和foriterator接近。

 

3、遍历方式性能测试结果分析

(1)foreach介绍

foreach是JavaSE5.0引入的功能很强的循环构造,for(Integerj:

list)应读作foreachintinlist。

for(Integerj:

list)实现几乎等价于

Java

1

2

3

4

Iteratoriterator=list.iterator();

while(iterator.hasNext()){

Integerj=iterator.next();

}

下面的分析会将foreach和显示调用集合迭代器两种遍历方式归类为Iterator方式,其他三种称为get方式遍历。

这时我们已经发现foreach的一大好处,简单一行实现了四行的功能,使得代码简洁美观,另一大好处是相对于下标循环而言的,foreach不必关心下标初始值和终止值及越界等,所以不易出错。

Effective-Java中推荐使用此种写法遍历,本文会验证这个说法。

 

使用foreach构造的类对象必须实现了Iterable接口,Java的Collection继承自此接口,List实现了Collection,这个接口仅包含一个函数,源码如下:

Java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

packagejava.lang;

 

importjava.util.Iterator;

 

/**

*Implementingthisinterfaceallowsanobjecttobethetargetof

*the"foreach"statement.

*

*paramthetypeofelementsreturnedbytheiterator

*

*since1.5

*/

publicinterfaceIterable{

 

    /**

    *ReturnsaniteratoroverasetofelementsoftypeT.

    *

    *returnanIterator.

    */

    Iteratoriterator();

}

iterator()用于返回一个Iterator,从foreach的等价实现中我们可以看到,会调用这个函数得到Iterator,再通过Iterator的next()得到下一个元素,hasNext()判断是否还有更多元素。

Iterator源码如下:

Java

1

2

3

4

5

6

7

publicinterfaceIterator{

    booleanhasNext();

 

    Enext();

 

    voidremove();

}

 

(2)ArrayList遍历方式结果分析

1

2

3

4

5

6

7

8

9

10

11

12

13

14

pareloopperformanceofArrayList

-----------------------------------------------------------------------

listsize              |10,000    |100,000  |1,000,000|10,000,000

-----------------------------------------------------------------------

foreach              |1ms      |3ms      |14ms    |152ms    

-----------------------------------------------------------------------

foriterator          |0ms      |1ms      |12ms    |114ms    

-----------------------------------------------------------------------

forlist.size()        |1ms      |1ms      |13ms    |128ms    

-----------------------------------------------------------------------

forsize=list.size()|0ms      |0ms      |6ms      |62ms    

-----------------------------------------------------------------------

forj--                |0ms      |1ms      |6ms      |63ms    

-----------------------------------------------------------------------

PS:

由于首次遍历List会稍微多耗时一点,foreach的结果稍微有点偏差,将测试代码中的几个Type顺序调换会发现,foreach耗时和foriterator接近。

从上面我们可以看出:

a.在ArrayList大小为十万之前,五种遍历方式时间消耗几乎一样

b.在十万以后,第四、五种遍历方式快于前三种,get方式优于Iterator方式,并且

Java

1

2

3

4

intsize=list.size();

for(intj=0;j

list.get(j);

}

用临时变量size取代list.size()性能更优。

我们看看ArrayList中迭代器Iterator和get方法的实现

Java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

privateclassItrimplementsIterator{

intcursor;      //indexofnextelementtoreturn

intlastRet=-1;//indexoflastelementreturned;-1ifnosuch

intexpectedModCount=modCount;

 

publicbooleanhasNext(){

returncursor!

=size;

}

 

SuppressWarnings("unchecked")

publicEnext(){

checkForodification();

inti=cursor;

if(i>=size)

thrownewNoSuchElementException();

Object[]elementData=ArrayList.this.elementData;

if(i>=elementData.length)

thrownewConcurrentModificationException();

cursor=i+1;

return(E)elementData[lastRet=i];

}

……

}

 

publicEget(intindex){

rangeCheck(index);

 

returnelementData(index);

}

从中可以看出get和Iterator的next函数同样通过直接定位数据获取元素,只是多了几个判断而已。

c.从上可以看出即便在千万大小的ArrayList中,几种遍历方式相差也不过50ms左右,且在常用的十万左右时间几乎相等,考虑foreach的优点,我们大可选用foreach这种简便方式进展遍历。

 

(3)LinkedList遍历方式结果分析

1

2

3

4

5

6

7

8

9

10

11

12

13

14

pareloopperformanceofLinkedList

-----------------------------------------------------------------------

listsize              |100      |1,000    |10,000    |100,000  

-----------------------------------------------------------------------

foreach              |0ms      |1ms      |1ms      |2ms      

-----------------------------------------------------------------------

foriterator          |0ms      |0ms      |0ms      |2ms      

-----------------------------------------------------------------------

forlist.size()        |0ms      |1ms      |73ms    |7972ms  

-----------------------------------------------------------------------

forsize=list.size()|0ms      |0ms      |67ms    |8216ms  

-----------------------------------------------------------------------

forj--                |0ms      |1ms      |67ms    |8277ms  

-----------------------------------------------------------------------

PS:

由于首次遍历List会稍微多耗时一点,foreach的结果稍微有点偏差,将测试代码中的几个Type顺序调换会发现,foreach耗时和foriterator接近。

从上面我们可以看出:

a在LinkedList大小接近一万时,get方式和Iterator方式就已经差了差不多两个数量级,十万时Iterator方式性能已经远胜于get方式。

我们看看LinkedList中迭代器和get方法的实现

Java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

privateclassListItrimplementsListIterator{

privateNodelastReturned=null;

privateNodenext;

privateintnextIndex;

privateintexpectedModCount=modCount;

 

ListItr(intindex){

//assertisPositionIndex(index);

next=(index==size)?

null:

node(index);

nextIndex=index;

}

 

publicbooleanhasNext(){

returnnextIndex

}

 

publicEnext(){

checkForodification();

if(!

hasNext())

thrownewNoSuchElementException();

 

lastReturned=next;

next=next.next;

nextIndex++;

returnlastReturned.item;

}

……

}

 

publicEget(intindex){

checkE

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 简洁抽象

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1