普通for循环语法:

 for (int i = 0; i < integers.length; i++) {
System.out.println(intergers[i]);
}

foreach 循环语法:

 for(Integer in : integers){
System.out.println(in);
}

今天我们来比较一下两种for循环对ArrayList和LinkList集合的循环性能比较。首先简单的了解一下ArrayList和LinkList的区别:

ArrayList:ArrayList是采用数组的形式保存对象的,这种方式将对象放在连续的内存块中,所以插入和删除时比较麻烦,查询比较方便。

LinkList:LinkList是将对象放在独立的空间中,而且每个空间中还保存下一个空间的索引,也就是数据结构中的链表结构,插入和删除比较方便,但是查找很麻烦,要从第一个开始遍历。

下面是我测试的代码:

 package cn.migu.newportal.activity.service.activity;

 import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List; /**
*
* @author
* @version C10 2017年11月30日
* @since SDP V300R003C10
*/
public class Test
{
public static void main(String[] args)
{ // 实例化arrayList
List<Integer> arrayList = new ArrayList<Integer>();
// 实例化linkList
List<Integer> linkList = new LinkedList<Integer>(); // 插入10万条数据
for (int i = 0; i < 100000; i++)
{
arrayList.add(i);
linkList.add(i);
} int array = 0;
// 用for循环arrayList
long arrayForStartTime = System.currentTimeMillis();
for (int i = 0; i < arrayList.size(); i++)
{
array = arrayList.get(i);
}
long arrayForEndTime = System.currentTimeMillis();
System.out.println("用for循环arrayList 10万次花费时间:" + (arrayForEndTime - arrayForStartTime) + "毫秒"); // 用foreach循环arrayList
long arrayForeachStartTime = System.currentTimeMillis();
for (Integer in : arrayList)
{
array = in;
}
long arrayForeachEndTime = System.currentTimeMillis();
System.out.println("用foreach循环arrayList 10万次花费时间:" + (arrayForeachEndTime - arrayForeachStartTime) + "毫秒"); // 用for循环linkList
long linkForStartTime = System.currentTimeMillis();
int link = 0;
for (int i = 0; i < linkList.size(); i++)
{
link = linkList.get(i);
}
long linkForEndTime = System.currentTimeMillis();
System.out.println("用for循环linkList 10万次花费时间:" + (linkForEndTime - linkForStartTime) + "毫秒"); // 用froeach循环linkList
long linkForeachStartTime = System.currentTimeMillis();
for (Integer in : linkList)
{
link = in;
}
long linkForeachEndTime = System.currentTimeMillis();
System.out.println("用foreach循环linkList 10万次花费时间:" + (linkForeachEndTime - linkForeachStartTime) + "毫秒");
}
}

循环10万次的时候,控制台打印结果:  (结果每次都会变,但求个平均值还是可以分析出结果的)

用for循环arrayList 10万次花费时间:6毫秒
用foreach循环arrayList 10万次花费时间:7毫秒
用for循环linkList 10万次花费时间:20489毫秒
用foreach循环linkList 10万次花费时间:8毫秒

可以看出,循环ArrayList时,普通for循环比foreach循环花费的时间要少一点;循环LinkList时,普通for循环比foreach循环花费的时间要多很多。

当我将循环次数提升到一百万次的时候,循环ArrayList,普通for循环还是比foreach要快一点;但是普通for循环在循环LinkList时,程序直接卡死。

结论:需要循环数组结构的数据时,建议使用普通for循环,因为for循环采用下标访问,对于数组结构的数据来说,采用下标访问比较好。

需要循环链表结构的数据时,一定不要使用普通for循环,这种做法很糟糕,数据量大的时候有可能会导致系统崩溃。

网上参考一种代码更紧凑的写法:

实体Person类

 package cn.migu.newportal.activity.service.activity;

 /**
*
* @author
* @version C10 2017年11月30日
* @since SDP V300R003C10
*/
public class Person
{
private String a; private int b; public Person(String a, int b)
{
super();
this.a = a;
this.b = b;
} public String getA()
{
return a;
} public void setA(String a)
{
this.a = a;
} public int getB()
{
return b;
} public void setB(int b)
{
this.b = b;
} }

测试ArrayList的主程序:

 package com.zhang.loop;  

 import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List; public class TestArrayList {
private static final int COUNT = 800000;
private static List<Person> persons = new ArrayList<Person>(); public static void main(String[] args) {
init();
System.out.println("for循环测试结果:"+testFor());
System.out.println("foreach循环测试结果:"+testForeach());
System.out.println("iterator循环测试结果:"+testIterator());
} //初始化集合
public static void init(){
for (int i = 0; i <COUNT; i++) {
persons.add(new Person("第"+i+"个元素",i));
}
}
//for循环便利集合
public static long testFor(){
long start = System.nanoTime();
Person p = null;
for (int i = 0; i < persons.size(); i++) {
p = persons.get(i);
}
return (System.nanoTime()-start)/1000;
}
//foreach循环便利集合
public static long testForeach(){
long start = System.nanoTime();
Person p = null;
for (Person person : persons) {
p = person;
}
return (System.nanoTime()-start)/1000;
}
//iterator循环便利集合
public static long testIterator(){
long start = System.nanoTime();
Person p = null;
Iterator<Person> itreator = persons.iterator();
while(itreator.hasNext()){
p = itreator.next();
}
return (System.nanoTime()-start)/1000;
} }

ArrayList测试结果:

测试LinkedList的主程序:

 package com.zhang.loop;  

 import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List; public class TestArrayList {
private static final int COUNT = 8000;
private static List<Person> persons = new LinkedList<Person>(); public static void main(String[] args) {
init();
System.out.println("for循环测试结果:"+testFor());
System.out.println("foreach循环测试结果:"+testForeach());
System.out.println("iterator循环测试结果:"+testIterator());
} //初始化集合
public static void init(){
for (int i = 0; i <COUNT; i++) {
persons.add(new Person("第"+i+"个元素",i));
}
}
//for循环便利集合
public static long testFor(){
long start = System.nanoTime();
Person p = null;
for (int i = 0; i < persons.size(); i++) {
p = persons.get(i);
}
return (System.nanoTime()-start)/1000;
}
//foreach循环便利集合
public static long testForeach(){
long start = System.nanoTime();
Person p = null;
for (Person person : persons) {
p = person;
}
return (System.nanoTime()-start)/1000;
}
//iterator循环便利集合
public static long testIterator(){
long start = System.nanoTime();
Person p = null;
Iterator<Person> itreator = persons.iterator();
while(itreator.hasNext()){
p = itreator.next();
}
return (System.nanoTime()-start)/1000;
} }

LinkedList测试结果:

记录的存取方式有两种:

一种是顺序存储(数组,ArrayList..)可以根据其下标找到对应的记录

另一种是链接存储(LinkedList..)链接存储(拿单链表为例)则必须找到其前一个记录的位置才能够找到本记录。

根据以上可以得到的结果是:for循环便于访问顺序存储的记录,而foreach和迭代器便于访问链接存储。

java中三种for循环之间的对比的更多相关文章

  1. Java中几种常用数据类型之间转换的方法

    Java中几种常用的数据类型之间转换方法: 1. short-->int 转换 exp: short shortvar=0; int intvar=0; shortvar= (short) in ...

  2. java设计模式---三种工厂模式之间的区别

    简单工厂,工厂方法,抽象工厂都属于设计模式中的创建型模式.其主要功能都是帮助我们把对象的实例化部分抽取了出来,优化了系统的架构,并且增强了系统的扩展性. 本文是本人对这三种模式学习后的一个小结以及对他 ...

  3. 关于java中三种初始化块的执行顺序

    许多小伙伴对于java中的三种初始化块的执行顺序一直感到头疼,接下来我们就来分析一下这三种初始化块到底是怎么运行的.有些公司也会将这个问题作为笔试题目. 下面通过一段代码来看看创建对象时这么初始化块是 ...

  4. java中三种方式获得类的字节码文件对象

    package get_class_method; public class ReflectDemo { /** * @param args */ public static void main(St ...

  5. Java使用三种不同循环结构对1+2+3+...+100 求和

    ▷//第一种求法,使用while结构 /** * @author 9527 * @since 19/6/20 */ public class Gaosi { public static void ma ...

  6. Java中两种实现多线程方式的对比分析

    本文转载自:http://www.linuxidc.com/Linux/2013-12/93690.htm#0-tsina-1-14812-397232819ff9a47a7b7e80a40613cf ...

  7. Go_18: Golang 中三种读取文件发放性能对比

    Golang 中读取文件大概有三种方法,分别为: 1. 通过原生态 io 包中的 read 方法进行读取 2. 通过 io/ioutil 包提供的 read 方法进行读取 3. 通过 bufio 包提 ...

  8. Golang 中三种读取文件发放性能对比

    Golang 中读取文件大概有三种方法,分别为: 1. 通过原生态 io 包中的 read 方法进行读取 2. 通过 io/ioutil 包提供的 read 方法进行读取 3. 通过 bufio 包提 ...

  9. Java中三种比较常见的数组排序

    我们学习数组比较常用的数组排序算法不是为了在工作中使用(这三个算法性能不高),而是为了练习for循环和数组.因为在工作中Java API提供了现成的优化的排序方法,效率很高,以后工作中直接使用即可 . ...

随机推荐

  1. ipython output logging:使用日志记录输出

    通常使用ipython的%logstart日志功能时,仅开启输入的记录. 例如在ipython中开启%logstart后,记录的日志文件内容如下: #!/usr/bin/env python # 20 ...

  2. 部署php的正确姿势

    1. 更新源 apt-get update 2.安装apache apt-get install apache2 ubuntu下apache2虚拟主机配置 cd /etc/apache2/sites- ...

  3. ES6 class的基本语法-学习笔记

    1.基本上,ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰.更像面向对象编程的语法而已. 类的内部所有定义的方法,都是 ...

  4. json与cjson

    json安装: http://blog.csdn.net/u011641885/article/details/46755225 tar xvf json-c-0.9.tar.gz cd json-c ...

  5. svn 创建branch merge

    使用TortoiseSVN 创建分支 1.TortoiseSVN(右键)->Repo-browser进入仓库 2.选择需要创建分支的文件->Copy to 3.将新创建branch pat ...

  6. 2.11 alert\confirm\prompt

    2.11 alert\confirm\prompt 前言   不是所有的弹出框都叫alert,在使用alert方法前,先要识别出到底是不是alert.先认清楚alert长什么样子,下次碰到了,就可以用 ...

  7. jupyter环境安装

    jupyter notebook环境安装 一.什么是Jupyter Notebook? 1. 简介 Jupyter Notebook是基于网页的用于交互计算的应用程序.其可被应用于全过程计算:开发.文 ...

  8. [LeetCode&Python] Problem 788. Rotated Digits

    X is a good number if after rotating each digit individually by 180 degrees, we get a valid number t ...

  9. 回文树&后缀自动机&后缀数组

    KMP,扩展KMP和Manacher就不写了,感觉没多大意思.   之前感觉后缀自动机简直可以解决一切,所以不怎么写后缀数组.   马拉车主要是通过对称中心解决问题,有的时候要通过回文串的边界解决问题 ...

  10. BFS广度优先搜索 炸弹人

    题面:一个人在一个坐标放炸弹,请问可以可以杀死的敌人数目最大是,并且输出该点的坐标 G代表敌人 .代表该位置可以走 "#"代表该位置存在障碍物 并且防止炸弹的蔓13 13 3 3 ...