A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 刘蕴学 中级黑马   /  2012-5-22 23:24  /  9774 人查看  /  15 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 刘蕴学 于 2012-5-22 23:26 编辑

测试ArrayList和LinkedList哪个遍历快的,当然传统说法是Linkedlist快,但是我这里不一样,麻烦大家把下边这个代码运行一次之后贴一下控制台信息

这是我的测试结果,可能时间会长一些,机器不太好的话要好几分钟
  1. arraylist size 100000
  2. linkedlist size 100000
  3. ------
  4. arraylist get(n) time 10367
  5. arraylist iterator time 1286
  6. arraylist foreach time 12161
  7. linkedlist get(n) time 923540000
  8. linkedlist iterator time 42136
  9. linkedlist foreach time 24316
复制代码

  1. package tetris;

  2. import java.util.ArrayList;
  3. import java.util.Iterator;
  4. import java.util.LinkedList;
  5. import java.util.Random;

  6. public class TestList
  7. {
  8.         
  9.         private static Random random = new Random();
  10.         
  11.         public static void main(String[] args)
  12.         {
  13.         
  14.                 ArrayList<String> arraylist = new ArrayList<String>();
  15.                 LinkedList<String> linkedlist = new LinkedList<String>();
  16.                 Iterator<String> iterator = null;
  17.                 for (int i = 0; i < 100000; i++)
  18.                 {
  19.                         String r = randomString();
  20.                         arraylist.add(r);
  21.                         linkedlist.add(r);
  22.                 }
  23.                
  24.                 System.out.println("arraylist size " + arraylist.size());
  25.                 System.out.println("linkedlist size " + linkedlist.size());
  26.                 System.out.println("------");
  27.                 long begin = System.currentTimeMillis();
  28.                 for (int i = 0; i < 10000; i++)
  29.                 {
  30.                         for (int j = 0; j < arraylist.size(); j++)
  31.                         {
  32.                                 String s = arraylist.get(j);
  33.                         }
  34.                 }
  35.                 System.out.println("arraylist get(n) time " + (System.currentTimeMillis() - begin));
  36.                
  37.                
  38.                 begin = System.currentTimeMillis();
  39.                 for (int i = 0; i < 10000; i++)
  40.                 {
  41.                         iterator = arraylist.iterator();
  42.                         while (iterator.hasNext())
  43.                         {
  44.                                 iterator.next();
  45.                         }
  46.                 }
  47.                 System.out.println("arraylist iterator time " + (System.currentTimeMillis() - begin));
  48.                
  49.                 begin = System.currentTimeMillis();
  50.                 for (int i = 0; i < 10000; i++)
  51.                 {
  52.                         for (String s:arraylist)
  53.                         {
  54.                                 
  55.                         }
  56.                 }
  57.                 System.out.println("arraylist foreach time " + (System.currentTimeMillis() - begin));
  58.                
  59.                 begin = System.currentTimeMillis();
  60.                 for (int i = 0; i < 1; i++)
  61.                         for (int j = 0; j < linkedlist.size(); j++)
  62.                         {
  63.                                 String s = linkedlist.get(j);
  64.                         }
  65.                 System.out.println("linkedlist get(n) time " + (System.currentTimeMillis() - begin) * 10000);
  66.                
  67.                
  68.                 begin = System.currentTimeMillis();
  69.                 for (int i = 0; i < 10000; i++)
  70.                 {
  71.                         iterator = linkedlist.iterator();
  72.                         while (iterator.hasNext())
  73.                         {
  74.                                 iterator.next();
  75.                         }
  76.                 }
  77.                 System.out.println("linkedlist iterator time " + (System.currentTimeMillis() - begin));
  78.                
  79.                 begin = System.currentTimeMillis();
  80.                 for (int i = 0; i < 10000; i++)
  81.                 {
  82.                         for (String s:linkedlist)
  83.                         {
  84.                                 
  85.                         }
  86.                 }
  87.                 System.out.println("linkedlist foreach time " + (System.currentTimeMillis() - begin));        
  88.         }
  89.         
  90.         protected static String randomString()
  91.         {
  92.         
  93.                 return Long.toString(random.nextLong(), 36);
  94.         }
  95. }
复制代码

15 个回复

倒序浏览
D:\SYSTEM\桌面\未命名.jpg
回复 使用道具 举报
这个样..

未命名.jpg (23.95 KB, 下载次数: 138)

貌似隔很远

貌似隔很远
回复 使用道具 举报
arraylist size 100000
linkedlist size 100000
------
arraylist get(n) time 14406
arraylist iterator time 51235
arraylist foreach time 57625
linkedlist get(n) time 215470000
linkedlist iterator time 27328
linkedlist foreach time 28031
回复 使用道具 举报
本帖最后由 尹丽峰 于 2012-5-23 00:05 编辑

回复 使用道具 举报
遍历应该是array快吧,arraylist是开辟一片连续的内存,不需要引用指向下一个,节约内存空间,便利也比较快吧
   数据结构是这么说的
回复 使用道具 举报
余宏 中级黑马 2012-5-23 00:08:58
7#
要是这两者进行遍历到底谁快的问题还真的很难说。一般遍历应该是arraylist快 删除和添加是linkedlist快, 数组大小也会影响效率
回复 使用道具 举报
何周舟 黑马帝 2012-5-23 00:23:58
8#
ArrayList 存储地址值的内存区域是连续 遍历时查找下一个元素需要的时间较少
LinkedList 存储地址值的内存区域不是连续  是前一个元素存储后一个元素的地址值 当删除一个元素时 只需要修改被删除元素前一个元素中记录后一个元素的地址值即可 所以LinkedList在增删方面比较快
回复 使用道具 举报
褚代江 来自手机 中级黑马 2012-5-23 00:37:50
9#
这个还是link快,只是你link循环时给赋值了,然后你get时,link取值要慢,你把取值去掉就看出来了,明把代码贴出来,断网了啊
回复 使用道具 举报
褚代江 来自手机 中级黑马 2012-5-23 00:38:58
10#
这个还是link快,只是你link循环时给赋值了,然后你get时,link取值要慢,你把取值去掉就看出来了,明把代码贴出来,断网了啊
回复 使用道具 举报
查询:ArrayList快(底层数据结构是数组)
增删:LinkedList快(底层数据结构式链表)
遍历:LinkedList快(底层是链表,每个节点是一个对象,对象与对象间用引用连接,遍历时只需next = next.next实现引用的向后移动。而Java里ArrayList存的是对象数组,遍历时要使引用向后移动,就不是简单把引用的值加一就能实现了,可能要算出下一个对象的引用然后再赋给当前引用。所以集合的遍历还是LinkedList快。如果是遍历基本类型的数组,应该是数组快。个人理解,请参考)

点评

不要光下结论,你无法证明为什么Linkedlist快,数据结构大家也都知道,这没什么好说的,主要还是不同环境的差异为什么这么明显  发表于 2012-5-23 08:11
回复 使用道具 举报
arraylist size 100000
linkedlist size 100000
------
arraylist get(n) time 24277
arraylist iterator time 286
arraylist foreach time 70406
linkedlist get(n) time 482700000
linkedlist iterator time 79710
linkedlist foreach time 84318

给个参考,似乎这样比较结论不好说吧。

点评

看来局部差异并不光我自己的嘛,哈哈,这个东西暂时没想到好的办法来说明  发表于 2012-5-23 08:12
回复 使用道具 举报
本帖最后由 隋丙跃 于 2012-5-23 03:09 编辑
  1. arraylist size 100000
  2. linkedlist size 100000
  3. ------
  4. arraylist get(n) time 7355
  5. arraylist iterator time 1799
  6. arraylist foreach time 7956
  7. linkedlist get(n) time 218400000
  8. linkedlist iterator time 10764
  9. linkedlist foreach time 11289
复制代码
单单是遍历的话链表不快的吧!ArrayList的中元素的内存地址是连续的,而链表由于其具有双向指针,所以可以存放在内存中的不同位置,遍历的时候虽然当前节点可以指向next,但cpu就要到另一片空间去寻找该地址所存储的内容。删除的话也可以试一下 应该是LinkedList快一些,ArrayList删除一个元素,后面的元素位置都要发生变化,而Linked只需要修改指针节点就哦了。至于楼上说LinkedList节约内存空间,这个不大清楚,LinkedList元素内容中除了值还需要维护2个节点指针呢,估计是利于内存管理吧!想存哪里就存哪里,这块空间不够了,就存其他的地方,而ArrayList需要连续的一片空间。

点评

在我机器上,无论做什么操作,甚至是随机访问,都是ArrayList快,网上的结论全部被推翻  发表于 2012-5-23 08:13
回复 使用道具 举报
我猜可能是编译器版本的问题,我的是1.6.0.31,编译器会将迭代器循环中增加Linkedlist的get操作,这个应该是问题的关键,但貌似很多人的情况并不是这样。。。。
回复 使用道具 举报
  1. import java.util.ArrayList;
  2. import java.util.Iterator;
  3. import java.util.LinkedList;
  4. import java.util.Random;

  5. public class TestList
  6. {
  7.         
  8.         private static Random random = new Random();
  9.         
  10.         public static void main(String[] args)
  11.         {
  12.         
  13.                 ArrayList<Integer> arraylist = new ArrayList<Integer>();
  14.                 LinkedList<Integer> linkedlist = new LinkedList<Integer>();
  15.                 Iterator<Integer> iterator = null;
  16.                 for (int i = 0; i < 100000; i++)
  17.                 {
  18.                         arraylist.add(i);//因为要看他们遍历的速度,所以很多因素都会影响,所以这里存入相同的东西
  19.                         linkedlist.add(i);
  20.                 }
  21.                
  22.                 System.out.println("arraylist size " + arraylist.size());
  23.                 System.out.println("linkedlist size " + linkedlist.size());
  24.                 System.out.println("-------------------------------------------");
  25.                 long begin = System.currentTimeMillis();
  26.                 for (int i = 0; i < 100000; i++)
  27.                 {
  28.                     int a=arraylist.size();
  29.                         for (int j = 0; j < a; j++)
  30.                         {
  31. //                            int m=arraylist.get(j);//每次都取出来的话,我们知道arraylist的查改快,所以这里打印出的时间包括
  32.                                                     //从Arraylist中取值的时间。和linkedlist对比的话,当然ArrayList取值快,
  33.                                                     //在打印时间时,可以看的很明白下面两图的时间可以看出来
  34.                         }
  35.                 }
  36.                 System.out.println("arraylist get(n) time " + (System.currentTimeMillis() - begin));
  37.    
  38. System.out.println("====================");

  39.                 begin = System.currentTimeMillis();
  40.                 for (int i = 0; i < 100000; i++)
  41.                 {
  42.                     int a=linkedlist.size();
  43.                         for (int j = 0; j < a; j++)
  44.                         {
  45. //                            int m=linkedlist.get(j);
  46.                         }
  47.                 }
  48.                 System.out.println("linkedlist get(n) time " + (System.currentTimeMillis() - begin) );        
  49.         }
  50. }
复制代码
//其实这里在不取值的时候。两次时间差是因为取了100000次linkedlist.size()的时间比ArrayList.size()短的时间。
//


//但是要遍历出集合中的数据(这里说的包括取出集合中的值,包括取值的时间的话)肯定是ArrayList的时间短,ArrayList比linkedlist取值块
//还是我们都知道的arraylist的查改快,linkedlist增删块,我觉得记着这个就好了,真的要得出集合中所有的值还是ArrayList比较好

1.jpg (17.46 KB, 下载次数: 129)

不取值的时候

不取值的时候

2.jpg (12.96 KB, 下载次数: 138)

取值的时候,link时间太长了就不等了

取值的时候,link时间太长了就不等了

点评

行啊,小厨子会写注释了啊,有进步  发表于 2012-5-23 12:36
回复 使用道具 举报
arraylist size 100000
linkedlist size 100000
------
arraylist get(n) time 6692
arraylist iterator time 36842
arraylist foreach time 37811
linkedlist get(n) time 87210000
linkedlist iterator time 11437
linkedlist foreach time 14335

为什么会差距这么大?  
我的明显 linkedlist 的iterator time  和foreach time  比arraylist的 iterator time  和foreach time  短。
老师的  linkedlist 的iterator time  和foreach time  比arraylist的 iterator time  和foreach time  长。 而且长那么多。


回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马