for i和for each和Java8的forEach性能测试,到底谁快的测试
2016-07-27 13:31
549 查看
有说这个快,有说那个快,但是,靠嘴不顶用啊。还是测试一下就知道啦。
(Lists.newArrayList(); 这个是guava里面的一个集合初始化的工具)
如下 :
先是main方法吧
然后是获取2个集合的方法。
然后就是三个性能方法
还有个打印时间的方法
最后就是这些个代码实际运行的结果
for i for arrayList 执行耗时 : 105 毫秒
for i for linkedList 执行耗时 : 22 毫秒
for each for arrayList 执行耗时 : 44 毫秒
for each for linkedList 执行耗时 : 25 毫秒
Lambda for arrayList 执行耗时 : 74 毫秒
Lambda for linkedList 执行耗时 : 44 毫秒
for i for arrayList 执行耗时 : 164 毫秒
for i for linkedList 执行耗时 : 29 毫秒
for each for arrayList 执行耗时 : 91 毫秒
for each for linkedList 执行耗时 : 27 毫秒
Lambda for arrayList 执行耗时 : 94 毫秒
Lambda for linkedList 执行耗时 : 43 毫秒
for i for arrayList 执行耗时 : 114 毫秒
for i for linkedList 执行耗时 : 26 毫秒
for each for arrayList 执行耗时 : 52 毫秒
for each for linkedList 执行耗时 : 28 毫秒
Lambda for arrayList 执行耗时 : 92 毫秒
Lambda for linkedList 执行耗时 : 54 毫秒
for i for arrayList 执行耗时 : 130 毫秒
for i for linkedList 执行耗时 : 45 毫秒
for each for arrayList 执行耗时 : 72 毫秒
for each for linkedList 执行耗时 : 30 毫秒
Lambda for arrayList 执行耗时 : 96 毫秒
Lambda for linkedList 执行耗时 : 45 毫秒
for i for arrayList 执行耗时 : 127 毫秒
for i for linkedList 执行耗时 : 26 毫秒
for each for arrayList 执行耗时 : 103 毫秒
for each for linkedList 执行耗时 : 36 毫秒
Lambda for arrayList 执行耗时 : 123 毫秒
Lambda for linkedList 执行耗时 : 58 毫秒
也就放这么几次的执行结果吧,有兴趣的可以自己跑一下。
为什么:
for each是jdk5.0新增加的一个循环结构,可以用来处理集合中的每个元素而不用考虑集合定下标。
格式就不说了
循环的集合:collection必须是一个数组或者是一个实现了lterable接口的类对象。
(Iterator<E> iterator(); List 集合实现了这个接口,它的子类当然也实现了,好吧collection也是实现的,所以这里可以看到的集合都可以用for each)
Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
使用for each循环语句的优势在于更加简洁,更不容易出错,不必关心下标的起始值和终止值。
forEach不是关键字,关键字还是for,语句是由iterator实现的,他们最大的不同之处就在于remove()方法上。
一般调用删除和添加方法都是具体集合的方法,例如:
List list = new ArrayList(); list.add(...); list.remove(...);
但是,如果在for each循环的过程中调用集合的remove()方法,就会导致循环出错,
因为循环过程中list.size()的大小变化了,就导致了错误。 所以,如果想在循环语句中删除集合中的某个元素,
就要用迭代器iterator的remove()方法,因为它的remove()方法不仅会删除元素,还会维护一个标志,
用来记录目前是不是可删除状态,这就涉及到源码了,想考虑了可以看下这个异常报错,链接如下:
( -->点击这个 http://blog.csdn.net/qq_27093465/article/details/52033629)
例如,你不能连续两次调用它的remove()方法,调用之前至少有一次next()方法的调用。
forEach就是为了让用iterator循环访问的形式简单,写起来更方便。当然功能不太全,所以但如有删除操作,还是要用它原来的形式。
使用for循环与使用迭代器iterator的对比
效率上的各有优势
采用ArrayList对随机访问比较快,而for循环中的get()方法,采用的即是随机访问的方法,因此在ArrayList里,for循环较快
采用LinkedList则是顺序访问比较快,iterator中的next()方法,采用的即是顺序访问的方法,因此在LinkedList里,使用iterator较快
从数据结构角度分析,for循环适合访问顺序结构,可以根据下标快速获取指定元素.而Iterator
适合访问链式结构,因为迭代器是通过next()和Pre()来定位的.可以访问没有顺序的集合.
而使用 Iterator 的好处在于可以使用相同方式去遍历集合中元素,而不用考虑集合类的内部实现(只要它实现了 java.lang.Iterable 接口),
如果使用 Iterator 来遍历集合中元素,一旦不再使用 List 转而使用 Set 来组织数据,
那遍历元素的代码不用做任何修改,如果使用 for 来遍历,
那所有遍历此集合的算法都得做相应调整,
因为List有序,Set无序,结构不同,
他们的访问算法也不一样.
可以了解下 继承list的几个类之间的差别,链接如下:
点击打开链接查看几个list之间的差别
(Lists.newArrayList(); 这个是guava里面的一个集合初始化的工具)
如下 :
先是main方法吧
/** * 测试不同for的效率问题 */ private static void testForEfficiency() { List<String> arrayList = CollectionUtil.getArrayList(); List<String> linkedList = CollectionUtil.getLinkedList(); testForI(arrayList, linkedList); testForEach(arrayList, linkedList); testForLambda(arrayList, linkedList); }
然后是获取2个集合的方法。
package com.lxk.util; import com.google.common.collect.Lists; import java.util.List; /** * 自定义集合告警类 * * @author lxk on 2017/11/13 */ public class CollectionUtil { private static final int SIZE = 1000000; /** * 获得底层是数组的list集合 */ public static List<String> getArrayList() { List<String> list = Lists.newArrayListWithExpectedSize(SIZE); for (Integer i = 0; i < SIZE; i++) { list.add(i.toString()); } return list; } /** * 获得底层是链表的list集合 */ public static List<String> getLinkedList() { List<String> list = Lists.newArrayListWithExpectedSize(SIZE); for (Integer i = 0; i < SIZE; i++) { list.add(i.toString()); } return list; } }
然后就是三个性能方法
/** * for i * * @param arrayList arrayList * @param linkedList linkedList */ private static void testForI(List<String> arrayList, List<String> linkedList) { int size = arrayList.size(); StringBuilder sb = new StringBuilder(); long a = System.currentTimeMillis(); for (int i = 0; i < size; i++) { sb.append(arrayList.get(i)); } PrintUtil.printRunTime(a, "for i for arrayList"); size = linkedList.size(); sb = new StringBuilder(); a = System.currentTimeMillis(); for (int i = 0; i < size; i++) { sb.append(linkedList.get(i)); } PrintUtil.printRunTime(a, "for i for linkedList"); } /** * for each * * @param arrayList arrayList * @param linkedList linkedList */ private static void testForEach(List<String> arrayList, List<String> linkedList) { StringBuilder sb = new StringBuilder(); long a = System.currentTimeMillis(); for (String s : arrayList) { sb.append(s); } PrintUtil.printRunTime(a, "for each for arrayList"); sb = new StringBuilder(); a = System.currentTimeMillis(); for (String s : linkedList) { sb.append(s); } PrintUtil.printRunTime(a, "for each for linkedList"); } /** * Java 8 的for循环 * * @param arrayList arrayList * @param linkedList linkedList */ private static void testForLambda(List<String> arrayList, List<String> linkedList) { StringBuilder sb = new StringBuilder(); long a = System.currentTimeMillis(); arrayList.forEach(sb::append); PrintUtil.printRunTime(a, "Lambda for arrayList"); sb = new StringBuilder(); a = System.currentTimeMillis(); linkedList.forEach(sb::append); PrintUtil.printRunTime(a, "Lambda for linkedList"); }
还有个打印时间的方法
package com.lxk.util; /** * @author lxk on 2017/9/27 */ public class PrintUtil { public static void divideLine() { System.out.println("--------------分界符--------------"); } /** * @param a long a=System.currentTimeMillis(); * @param describe 执行时间的描述 */ public static void printRunTime(long a, String describe) { System.out.println(describe + " 执行耗时 : " + (System.currentTimeMillis() - a) + " 毫秒 "); } }
最后就是这些个代码实际运行的结果
for i for arrayList 执行耗时 : 105 毫秒
for i for linkedList 执行耗时 : 22 毫秒
for each for arrayList 执行耗时 : 44 毫秒
for each for linkedList 执行耗时 : 25 毫秒
Lambda for arrayList 执行耗时 : 74 毫秒
Lambda for linkedList 执行耗时 : 44 毫秒
for i for arrayList 执行耗时 : 164 毫秒
for i for linkedList 执行耗时 : 29 毫秒
for each for arrayList 执行耗时 : 91 毫秒
for each for linkedList 执行耗时 : 27 毫秒
Lambda for arrayList 执行耗时 : 94 毫秒
Lambda for linkedList 执行耗时 : 43 毫秒
for i for arrayList 执行耗时 : 114 毫秒
for i for linkedList 执行耗时 : 26 毫秒
for each for arrayList 执行耗时 : 52 毫秒
for each for linkedList 执行耗时 : 28 毫秒
Lambda for arrayList 执行耗时 : 92 毫秒
Lambda for linkedList 执行耗时 : 54 毫秒
for i for arrayList 执行耗时 : 130 毫秒
for i for linkedList 执行耗时 : 45 毫秒
for each for arrayList 执行耗时 : 72 毫秒
for each for linkedList 执行耗时 : 30 毫秒
Lambda for arrayList 执行耗时 : 96 毫秒
Lambda for linkedList 执行耗时 : 45 毫秒
for i for arrayList 执行耗时 : 127 毫秒
for i for linkedList 执行耗时 : 26 毫秒
for each for arrayList 执行耗时 : 103 毫秒
for each for linkedList 执行耗时 : 36 毫秒
Lambda for arrayList 执行耗时 : 123 毫秒
Lambda for linkedList 执行耗时 : 58 毫秒
也就放这么几次的执行结果吧,有兴趣的可以自己跑一下。
为什么:
for each是jdk5.0新增加的一个循环结构,可以用来处理集合中的每个元素而不用考虑集合定下标。
格式就不说了
循环的集合:collection必须是一个数组或者是一个实现了lterable接口的类对象。
(Iterator<E> iterator(); List 集合实现了这个接口,它的子类当然也实现了,好吧collection也是实现的,所以这里可以看到的集合都可以用for each)
Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
使用for each循环语句的优势在于更加简洁,更不容易出错,不必关心下标的起始值和终止值。
forEach不是关键字,关键字还是for,语句是由iterator实现的,他们最大的不同之处就在于remove()方法上。
一般调用删除和添加方法都是具体集合的方法,例如:
List list = new ArrayList(); list.add(...); list.remove(...);
但是,如果在for each循环的过程中调用集合的remove()方法,就会导致循环出错,
因为循环过程中list.size()的大小变化了,就导致了错误。 所以,如果想在循环语句中删除集合中的某个元素,
就要用迭代器iterator的remove()方法,因为它的remove()方法不仅会删除元素,还会维护一个标志,
用来记录目前是不是可删除状态,这就涉及到源码了,想考虑了可以看下这个异常报错,链接如下:
( -->点击这个 http://blog.csdn.net/qq_27093465/article/details/52033629)
例如,你不能连续两次调用它的remove()方法,调用之前至少有一次next()方法的调用。
forEach就是为了让用iterator循环访问的形式简单,写起来更方便。当然功能不太全,所以但如有删除操作,还是要用它原来的形式。
使用for循环与使用迭代器iterator的对比
效率上的各有优势
采用ArrayList对随机访问比较快,而for循环中的get()方法,采用的即是随机访问的方法,因此在ArrayList里,for循环较快
采用LinkedList则是顺序访问比较快,iterator中的next()方法,采用的即是顺序访问的方法,因此在LinkedList里,使用iterator较快
从数据结构角度分析,for循环适合访问顺序结构,可以根据下标快速获取指定元素.而Iterator
适合访问链式结构,因为迭代器是通过next()和Pre()来定位的.可以访问没有顺序的集合.
而使用 Iterator 的好处在于可以使用相同方式去遍历集合中元素,而不用考虑集合类的内部实现(只要它实现了 java.lang.Iterable 接口),
如果使用 Iterator 来遍历集合中元素,一旦不再使用 List 转而使用 Set 来组织数据,
那遍历元素的代码不用做任何修改,如果使用 for 来遍历,
那所有遍历此集合的算法都得做相应调整,
因为List有序,Set无序,结构不同,
他们的访问算法也不一样.
可以了解下 继承list的几个类之间的差别,链接如下:
点击打开链接查看几个list之间的差别
相关文章推荐
- maven安装配置以及在eclipse中的配置
- Spring系列之Java代理机制实现AOP
- 二分查找算法----java实现
- JAVA实践基于DFS的图割点
- struts2的搭建简单测试程序
- Eclipse LogCat相关 (1.Unexpected value from nativeGetEnabledTags: 0 2.LogCat日志不出现 3.建立日志分类快速查询标签)
- java使double保留两位小数的多方法 java保留两位小数
- Spring MVC异常处理
- Java设计模式透析之 —— 单例(Singleton)
- Spring(二) 依赖注入
- Java ArrayList转数组泛型方法错误ArrayStoreException处理办法
- eclipse创建aidl文件
- java反射知识点简单回顾
- Java数据持久层框架 MyBatis之背景知识三
- java入门的一个游戏
- 房贷计算器java版
- SpringMVC验证
- spring Junit测试项目例子
- 欢迎使用CSDN-markdown编辑器
- JAVA(六)函数和数组