foreach

最近使用foreach做集合循环遍历,就要了解一下他的原理


foreach是一种增强型的for循环,

for ( type element : array ){

    System.out.println( element );

}

for循环与foreach循环的对比

public class ForeachTest {

    public static void main(String args[]){

        int[] arr={1,2,3,4,5};
        /**
         * 旧式遍历
         */
        for(int i=0; i<arr.length;i++){
           System.out.println("旧式遍历"+arr[i]);
        }

        /**
         * 新式遍历
         */
        for (int element: arr) {
            System.out.println("新式遍历"+element);
        }


        /************************遍历二维数组***************************/
                int[][] arr2={{1,2,3},{4,5,6},{7,8,9}};
        /**
         * 旧式遍历
         */
        for (int j = 0; j < arr2.length; j++) {
            for (int z = 0; z < arr2[j].length; z++) {
                System.out.println(arr2[j][z]);
            }
        }
        /**
         * 新式遍历
         */
        for (int[] row : arr2) {
            for (int element : row) {
                System.out.println(element);
            }
        }

        /***************************遍历list*******************************/
        List<String> list = new ArrayList<String>();
        list.add("a");
        list.add("b");
        list.add("c");
        /**
         * 普通for循环遍历
         */
        for (int i=0;i<list.size();i++){
            System.out.println(list.get(i));
        }
        /**
         * 迭代器遍历
         */
        for (Iterator<String> iter=list.iterator(); iter.hasNext();){
            System.out.println(iter.next());
        }
        /**
         * 增强for
         */
        for (String str:list) {
            System.out.println(str);
        }
    }
}
通过对比发现,foreach在代码简洁性较高,提高代码的可读性。

下面是foreach的局限性

public class ForeachTest2 {

    public static void main(String args[]){
       //定义一个数组
        int arr[]=new int[4];
        for (int x:arr){
            System.out.println(x);
        }
        //通过索引给数组元素赋值

        for (int i=3;i>0;i--){
            arr[i]=i;
        }
    }
}

foreach无法使用集合或者数组的索引,这时需要使用for



foreach的实现原理

参考自http://blog.csdn.net/moqihao/article/details/51078464


foreach的字节码

// Method descriptor #10 ()V        /*V代表返回值是void*/  
// Stack: 2, Locals: 3              /*操作数栈需要2个slot,局部变量表需要3个slot*/  
public void display1();  
   0  aload_0 [this]                /*将this指针推至栈顶*/  
   1  getfield ambigous.ForEach.list : java.util.List [19]  /*获得域List对象,压入栈顶*/  
   4  invokeinterface java.util.List.iterator() : java.util.Iterator [21] [nargs: 1]    /*调用interface的iterator方法获得iterator对象*/  
   9  astore_2                      /*将其存到局部变量表的第三个slot中(此时第一个是this,第二个空)*/  
  10  goto 30                       /*跳转*/  
  13  aload_2                       /*将iterator对象推到栈顶*/  
  14  invokeinterface java.util.Iterator.next() : java.lang.Object [27] [nargs: 1]  /*调用iterator的next方法*/  
  19  checkcast java.lang.String [33]/*checkcast类型安全检查*/  
  22  astore_1 [s]                  /*将s存到第二块slot*/  
  23  getstatic java.lang.System.out : java.io.PrintStream [35] /*获取静态System.out对象*/  
  26  aload_1 [s]                   /*将s推到栈顶*/  
  27  invokevirtual java.io.PrintStream.println(java.lang.String) : void [41]   /*调用out.println方法*/  
  30  aload_2                       /*将iterator对象推到栈顶*/  
  31  invokeinterface java.util.Iterator.hasNext() : boolean [47] [nargs: 1]    /*调用iterator.hasNext方法*/  
  36  ifne 13                       /*如果结果非0,即true,跳转*/  
  39  return                        /*返回*/  

foreach的执行最终转换成了对iterator的调用

// Method descriptor #10 ()V  
// Stack: 2, Locals: 2  
public void display2();  
   0  aload_0 [this]  
   1  getfield ambigous.ForEach.list : java.util.List [19]  
   4  invokeinterface java.util.List.iterator() : java.util.Iterator [21] [nargs: 1]  
   9  astore_1 [it]  
  10  goto 28  
  13  getstatic java.lang.System.out : java.io.PrintStream [35]  
  16  aload_1 [it]  
  17  invokeinterface java.util.Iterator.next() : java.lang.Object [27] [nargs: 1]  
  22  checkcast java.lang.String [33]  
  25  invokevirtual java.io.PrintStream.println(java.lang.String) : void [41]  
  28  aload_1 [it]  
  29  invokeinterface java.util.Iterator.hasNext() : boolean [47] [nargs: 1]  
  34  ifne 13  
  37  return  



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值