几种循环的区别

转载 2016年05月31日 14:12:10
   a> for(String s:strArray){...}这种for循环是直接取数组中的值,而不是取数组中的引用地址,效率应该较高,缺点是不能给集合赋值
   b> for(int n=0;n<strArray.length;n++){...} ,输出集合中的内容时,效率较低,但可给集合赋值

总的来说,如果用数组实现的,那最好用普通for循环,因为下标索引速度更快。增强型的for循环,其实是用iterator迭代器来做的,迭代器适合链表格式的存储结构。

所以,公司里很多人的代码都不规范,或者没有考虑效率问题,只是单纯的完成系统功能,这是很不负责任的做法。为一个公司做事,就要把代码优化到最好,比如用普通型for循环,我们可以先在第一步算出集合的大小,这样就省去了每次都要计算集合大小。

int size =arraylist.size(); for(int i=0;i<size;i++)
这样做,就提高了代码的效率了。


写了一段代码来印证自己的理论:

    package com.netease.corp; 
    import java.util.ArrayList;
    import java.util.LinkedList;
    import java.util.List;

   public class ForIterator {
   private static long MAX_NUMBER=100000;

    public static void main(String[] args) {
    List<Integer> linkedList=new LinkedList<Integer>();
    List<Integer> arrayList=new ArrayList<Integer>();
    for(int i=0;i<MAX_NUMBER;i++){   //给两个list赋值
        linkedList.add(100);
        arrayList.add(100);
    }
    getForCirculationTime(linkedList);
    getForCirculationTime(arrayList);
   }


/**
 * 方法功能:获取两种for循环的时间
 * @param lists
 */
public static void getForCirculationTime(List<Integer> lists){
    long starTime=System.currentTimeMillis();
    int n=0;
    int size=lists.size();
    for(int i=0;i<size;i++){
        n=lists.get(i);
    }
    Class s =lists.getClass();   //获取class的名
    String name=s.getName();
    System.out.println(s+"普通for循环 调用get方法花的时间:"+(System.currentTimeMillis()-starTime));

    starTime=System.currentTimeMillis();
    for(int  in:lists){
        n=in;
    }
    System.out.println(s+"增强型的for循环get方法花的时间:"+(System.currentTimeMillis()-starTime));        
    System.out.println();
    }
}




1.手先增强for循环和iterator遍历的效果是一样的,也就说 
增强for循环的内部也就是调用iteratoer实现的,但是增强for循环 有些缺点,例如不能在增强循环里动态的删除集合内容。不能获取下标等。 
2.ArrayList由于使用数组实现,因此下标明确,最好使用普通循环。 
3.而对于 LinkedList 由于获取一个元素,要从头开始向后找,因此建议使用 增强for循环,也就是iterator。
 

以下例子证明第一点 
①     public static void removeEvensVer2(List<Integer> lst) 
    { 
        for (Integer x : lst) 
            if (x % 2 == 0) 
                lst.remove(x); 
        
        System.out.println(lst); 
    } 

②     public static void removeEvensVer3(List<Integer> lst) 
    { 
        Iterator<Integer> itr = lst.iterator(); 
        while (itr.hasNext()) 
            if (itr.next() % 2 == 0) 
                itr.remove(); 
     
        System.out.println(lst); 
    } 

①在运行时抛出异常,②正常 
原因分析:因为增强的for循环内部就是调用iterator实现的,在遍历的时候就将list转化为了迭代器,当迭代器被创建之后,如果从结构上对列表修改除非通过迭代器自身的remove、add方法,其他任何时间任何方式的修改,迭代器都会抛出ConcurrentModificationException异常。


Iterator(迭代器)
            作为一种设计模式,迭代器可以用于遍历一个对象,对于这个对象的底层结构开发人员不必去了解。

       java中的Iterator一般称为“轻量级”对象,创建它的代价是比较小的。这里笔者不会去考究迭代器这种

       设计模式,仅在JDK代码层面上谈谈迭代器的时候以及使用迭代器的好处。

Iterator详解
            Iterator是作为一个接口存在的,它定义了迭代器所具有的功能。这里我们就以Iterator接口来看,不考

       虑起子类ListIterator。其源码如下:  


迭代器(Iterator)

  迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构。迭代器通常被称为“轻量级”对象,因为创建它的代价小。

  Java中的Iterator功能比较简单,并且只能单向移动:

  (1) 使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。注意:iterator()方法是java.lang.Iterable接口,被Collection继承。

  (2) 使用next()获得序列中的下一个元素。

  (3) 使用hasNext()检查序列中是否还有元素。

  (4) 使用remove()将迭代器新返回的元素删除。

  Iterator是Java迭代器最简单的实现,为List设计的ListIterator具有更多的功能,它可以从两个方向遍历List,也可以从List中插入和删除元素。

迭代器应用:
 list l = new ArrayList();
 l.add("aa");
 l.add("bb");
 l.add("cc");
 for (Iterator iter = l.iterator(); iter.hasNext();) {
  String str = (String)iter.next();
  System.out.println(str);
 }
 /*迭代器用于while循环
 Iterator iter = l.iterator();
 while(iter.hasNext()){
  String str = (String) iter.next();
  System.out.println(str);
 }

上面两个都不怎么样,应该使用下面的形式:
 List<String> arraylist = new ArrayList<String>();
 for (String str:arraylist) {
    System.out.println(str);
 }

这做到了最好的封装性.




import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import java.util.LinkedList;

/**
 * IteratorTest
 * @author SageZk
 */
public class IteratorTest {

    public static long testForloops(List<String> list) {
        long start = 0L, end = 0L;
        @SuppressWarnings("unused")
        String le = null;
        start = System.nanoTime();
        for (int i = list.size() - 1; i >= 0; --i) {
            le = list.get(i);
        }
        end = System.nanoTime();
        return end - start;
    }

    public static long testIterator(List<String> list) {
        long start = 0L, end = 0L;
        @SuppressWarnings("unused")
        String le = null;
        start = System.nanoTime();
        Iterator<String> it = list.iterator();
        while (it.hasNext()) {
            le = it.next();
        }
        end = System.nanoTime();
        return end - start;
    }

    public static void main(String[] args) {
        //测试列表长度
        final int LEN = 10000;

        //初始化测试用数据
        List<String> arraylist = new ArrayList<String>();
        List<String> linkedlist = new LinkedList<String>();
        for (int i = 0; i < LEN; ++i) {
            String s = Integer.toString(i, 2);
            arraylist.add(s);
            linkedlist.add(s);
        }

        //打印测试结果
        final String FORMAT = "%1$-16s%2$-16s%3$16d\n";
        System.out.println("List\t\tType\t\tTime(nanoseconds)");
        System.out.println("-------------------------------------------------");
        System.out.printf(FORMAT, "ArrayList""for", testForloops(arraylist));
        System.out.printf(FORMAT, "ArrayList""Iterator", testIterator(arraylist));
        System.out.printf(FORMAT, "LinkedList""for", testForloops(linkedlist));
        System.out.printf(FORMAT, "LinkedList""Iterator", testIterator(linkedlist));
    }

}


以下是 3 组测试结果:

[code=BatchFile]List Type Time(nanoseconds)
-------------------------------------------------
ArrayList       for                      1189258
ArrayList       Iterator                 2365594
LinkedList      for                    152396254
LinkedList      Iterator                 2340801

List Type Time(nanoseconds)
-------------------------------------------------
ArrayList       for                      1235701
ArrayList       Iterator                 4249982
LinkedList      for                    149825606
LinkedList      Iterator                 2525531

List Type Time(nanoseconds)
-------------------------------------------------
ArrayList       for                      1198267
ArrayList       Iterator                 2584617
LinkedList      for                    150382451
LinkedList      Iterator                 2347994
[/code]


使用 Iterator 的好处在于可以使用相同方式去遍历集合(List 是有序集合)中元素,而不用考虑集合类的内部实现(只要它实现了 java.lang.Iterable 接口)。
比如楼主例子中,如果使用 Iterator 来遍历集合中元素,一旦不再使用 List 转而使用 TreeSet 来组织数据,那遍历元素的代码不用做任何修改,如果使用 for 来遍历,那所有遍历此集合的算法都得做相应调整。


java增强型for循环优缺点
优点:遍历元素方便。
缺点:在遍历的过程中不能对元素进行修改、删除等操作
注意问题:遍历的集合必须是实现Iterable接口


此处引用 -----------

1.增强for循环和iterator遍历的效果是一样的,也就说

增强for循环的内部也就是调用iteratoer实现的(可以查看编译后的文件),但是增强for循环 有些缺点,例如不能在增强循环里动态的删除集合内容。不能获取下标等。
2.ArrayList由于使用数组实现,因此下标明确,最好使用普通循环
3.而对于 LinkedList 由于获取一个元素,要从头开始向后找,因此建议使用 增强for循环,也就是iterator
下面的例子可以证明
public static void main(String[] args)
{
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < 5000000; i++)
{
list.add(11);
}


long start = System.currentTimeMillis();
int size = list.size();
int c1 = 1;
for (int i = 0; i < size; i++)
{
c1 = list.get(i);
}
System.out.println("for + get(i)方法: " + (System.currentTimeMillis() - start));


long start2 = System.currentTimeMillis();
for (int c2 : list)
{
}
System.out.println("Iterator(foreach)方法:" + (System.currentTimeMillis() - start2));
}
结果:
for + get(i)方法: 94
Iterator(foreach)方法:234
在把ArrayList改为LinkedList,我这里内存溢出了,于是list改成50000
结果:
for + get(i)方法: 6969
Iterator(foreach)方法:0
---------------------

所以在使用的时候适当选择就好了。



多线程中的区别- 
// for (Block b : __blocks) {
// b.onDraw(canvas);
// }
// Iterator<Block> it = __blocks.iterator();
// while(it.hasNext()){
// Block b = it.next();
// b.onDraw(canvas);
// }
for(int i = 0; i < __blocks.size(); i++){
__blocks.get(i).onDraw(canvas);
}
 另外外一个线程动态的改变__blocks的大小    只有普通for循环不报错,其他通过迭代器实现的
是先有一个拷贝,所以真正得到时 ,会报并发修改错误


参考链接:http://www.jianshu.com/p/2fecd8d66829


相关文章推荐

java中几种循环的用法

  • 2011年12月04日 16:46
  • 2KB
  • 下载

java for循环的几种写法

J2SE 1.5提供了另一种形式的for循环。借助这种形式的for循环,可以用更简单地方式来遍历数组和Collection等类型的对象。本文介绍使用这种循环的具体方式,说明如何自行定义能被这样遍历的类...

matlab跳出循环的几种方式的比较

  • 2015年11月05日 17:22
  • 24KB
  • 下载

java for循环的几种写法

  • 2012年12月08日 21:36
  • 46KB
  • 下载

java中for循环的几种写法

J2SE 1.5提供了另一种形式的for循环。借助这种形式的for循环,可以用更简单地方式来遍历数组和Collection等类型的对象。本文介绍使用这种循环的具体方式,说明如何自行定义能被这样遍历的类...

Delphi 跳出循环的几种方法

  • 2013年03月29日 11:23
  • 1KB
  • 下载

java for循环的几种写法

J2SE 1.5提供了另一种形式的for循环。借助这种形式的for循环,可以用更简单地方式来遍历数组和Collection等类型的对象。本文介绍使用这种循环的具体方式,说明如何自行定义能被这样遍历的类...

几种list循环的方法

List List maps = new ArrayList(); Map ccc; for (int i = 0; i < 10; i++) { ...

java for循环的几种写法

J2SE 1.5提供了另一种形式的for循环。借助这种形式的for循环,可以用更简单地方式来遍历数组和Collection等类型的对象。本文介绍使用这种循环的具体方式,说明如何自行定义能被这样遍历的类...
  • az44yao
  • az44yao
  • 2012年08月23日 09:42
  • 447
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:几种循环的区别
举报原因:
原因补充:

(最多只允许输入30个字)