Java中迭代列表中数据时几种循环写法的效率比较
Java中经常会用到迭代列表数据的情况,本文针对几种常用的写法进行效率比较。虽然网上已经有了类似的文章,但是对他们的结论并不认同。
常见的实现方法:
1.for循环:
- for(int i = 0; i < list.size(); i++)
- for(int i = 0, size = list.size(); i < size; i++)
一般人都会认为第二种写法效率高。
2.foreach:
- for(Object obj : list)
这是一种简洁的写法,只能对列表进行读取,无法修改。
3.while:
- int size = list.size();
- while(size-- > 0)
4.迭代:
- Object iter = list.iterator();
- while(iter.hasNext()) {
- iter.next();
- }
测试代码:
针对以上几种方法编写的测试代码。
- public static void main(String[] args) {
- List<Integer> list = new ArrayList<Integer>();
- int runTime = 1000;//执行次数
- for (int i = 0; i < 1000 * 1000; i++) {
- list.add(i);
- }
- int size = list.size();
- long currTime = System.currentTimeMillis();//开始分析前的系统时间
- //基本的for
- for(int j = 0; j < runTime; j++) {
- for (int i = 0; i < size; i++) {
- list.get(i);
- }
- }
- long time1 = System.currentTimeMillis();
- //foreach
- for(int j = 0; j < runTime; j++) {
- for (Integer integer : list) {
- }
- }
- long time2 = System.currentTimeMillis();
- for(int j = 0; j < runTime; j++) {
- //while
- int i = 0 ;
- while(i < size){
- list.get(i++);
- }
- }
- long time3 = System.currentTimeMillis();
- for(int j = 0; j < runTime; j++) {//普通for循环
- for (int i = 0; i < list.size(); i++) {
- list.get(i);
- }
- }
- long time4 = System.currentTimeMillis();
- for(int j = 0; j < runTime; j++) {//迭代
- Iterator<Integer> iter = list.iterator();
- while(iter.hasNext()) {
- iter.next();
- }
- }
- long time5 = System.currentTimeMillis();
- long time = time1 - currTime ;
- System.out.print("use for:" + time);
- time = time2 - time1;
- System.out.print("\tuse foreach:" + time);
- time = time3 - time2;
- System.out.print("\tuse while:" + time);
- time = time4 - time3;
- System.out.print("\tuse for2:" + time);
- time = time5 - time4;
- System.out.print("\tuse iterator:" + time);
- System.out.println();
- }
输出结果(JDK1.6):
1.
use for:8695 use foreach:17091 use while:6867 use for2:7741 use iterator:14144
2.
use for:8432 use foreach:18126 use while:6905 use for2:7893 use iterator:13976
3.
use for:8584 use foreach:17177 use while:6875 use for2:7707 use iterator:14345
结论:
1.针对列表的 foreach的效率是最低:
耗时是普通for循环的2倍以上。个人理解它的实现应该和iterator相似。
2. list.size()的开销很小:
list.size()次数多少对效率基本没有影响。查看ArrayList的实现就会发现,size()方法的只是返回了对象内的长度属性,并没有其它计算,所以只存在函数调用的开销。
对数组的测试:
应该主要是检测数据合法性时产生的。
将执行次数增加100万倍,这时可以看出结果基本相等,并没有明显的差异。说明:
4. 数组length也没有开销
可见数组长度并不是每次执行的时候都要计算的。联想一下Java创建数组的时候要求必须指定数组的长度,编译处理的时候显然没有把这个值抛弃掉。
网上有一篇类似的文章,它居然得出了一个foreach执行效率最高的结论。看一下它的测试代码就会发现一个要命的问题,它居然在执行每次循环的时候调用了System.out.print()方法将数组内容输出,难道他不知道这个操作耗时非常大吗,这样计算出的结果有什么用处呢。
Java中迭代列表中数据时几种循环写法的效率比较的更多相关文章
- salesforce lightning零基础学习(七) 列表展示数据时两种自定义编辑页面
上一篇Lightning内容描述的是LDS,通过LDS可以很方便的实例化一个对象的数据信息.当我们通过列表展示数据需要编辑时,我们常使用两种方式去处理编辑页面:Pop Up Window弹出修改详情以 ...
- C#程序中从数据库取数据时需注意数据类型之间的对应,int16\int32\int64
private void btn2_Click(object sender, RoutedEventArgs e) { using (SqlConnection ...
- asp.net mvc视图中使用entitySet类型数据时提示出错
asp.net mvc5视图中使用entitySet类型数据时提示以下错误 检查了一下引用,发现已经引用了System.Data.Linq了,可是还是一直提示出错, 后来发现还需要在Views文件夹下 ...
- SQL中使用UPDATE更新数据时一定要记得WHERE子句
我们在使用 SQL 中的 UPDATE 更新数据时,一般都不会更新表中的左右数据,所以我们更新的数据的 SQL 语句中会带有 WHERE 子句,如果没有WHERE子句,就回更新表中所有的数据,在 my ...
- selenium+java:获取列表中的值
selenium+java:获取列表中的值 (2011-08-23 17:14:48) 标签: 杂谈 分类: selenium 初步研究利用java+testNg框架下写selenium测试用例,今天 ...
- ArcGIS客户端API中加载大量数据的几种解决办法
ArcGIS客户端API中加载大量数据的几种解决办法 2011-03-25 18:17 REST风格的一切事物方兴未艾,ArcGIS Server的客户端API(Javascript/Flex/Sil ...
- java中对集合对象list的几种循环访问
java中对集合对象list的几种循环访问的总结如下 1 经典的for循环 public static void main(String[] args) { List<String> li ...
- (转)java中对集合对象list的几种循环访问总结
Java集合的Stack.Queue.Map的遍历 在集合操作中,常常离不开对集合的遍历,对集合遍历一般来说一个foreach就搞定了,但是,对于Stack.Queue.Map类型的遍历,还是有一 ...
- Java构造和解析Json数据的两种方法详解二
在www.json.org上公布了很多JAVA下的json构造和解析工具,其中org.json和json-lib比较简单,两者使用上差不多但还是有些区别.下面接着介绍用org.json构造和解析Jso ...
随机推荐
- java中的数据库事务处理
/*java使用事务处理,首先要求数据库支持事务,如使用MYSQL的事务功能,就要求mysql的表类型为Innodb,*/ /*InnoDB,是MySQL的数据库引擎之一 与传统的ISAM与MyISA ...
- lucene建立索引的过程
建立索引过程 用户提交数据=>solr建立索引=>调用lucene包建立索引 官方建立索引和查询索引的例子如下: http://lucene.apache.org/core/4_10_3/ ...
- asp.net 中的那些编译错误(1):控件包含代码块(即<% ... %>),因此无法修改控件集合
在编译页面的时候出现:控件包含代码块(即 <% ... %>),因此无法修改控件集合错误 一般原因是: 在<head runat="server">< ...
- 解决ASP.NET中ReportView与IE11的兼容性问题
前久发现以前用ReportView开发的一个软件的报表,在IE11上运行时出错,陆续查了好几天才解决了问题. 开发环境: VS2010,ReportView 10.0.402,RDLC报表模板 问题: ...
- GET or POST
w3school中是这么说的: 与 POST 相比,GET 更简单也更快,并且在大部分情况下都能用. 然而,在以下情况中,请使用 POST 请求: 无法使用缓存文件(更新服务器上的文件或数据库) 向服 ...
- cas配置全攻略(转)
转:http://www.blogjava.net/tufanshu/archive/2011/01/21/343290.html 经过将近两天的测试,参考众多网友的贡献,终于完成了对cas的主要配置 ...
- 几种常见ECG数据格式及对比
SCP.DICOM.HL7aECG.GDF格式及对比 本文档首先给出SCP.DICOM.HL7aECG.GDF四种心电信号格式的具体数据结构,然后分析其各自的特点及适用范围. 一.SCP-ECG fo ...
- cmakelists 语法学习
1.项目最外层cmake编写:----------用于kdevelop编译器 project(filtering) cmake_minimum_required(VERSION 2.8) ————必须 ...
- Swift互用性:与 C的API交互(Swift 2.0版)-b
节包含内容: 基本数据类型(Primitive Types) 枚举(Enumerations) 指针(Pointer) 全局常量(Global Constants) 预处理指令(Preprocesso ...
- mybatis框架搭建学习初步
mybatis框架搭建步骤:1. 拷贝jar到lib目录下,而且添加到工程中2. 创建mybatis-config.xml文件,配置数据库连接信息 <environments default=& ...