下面看看示例代码:
public static void main(String[] args) { List<Integer> lists = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); lists.forEach(x -> { if (x < 5) { //continue; //编译报错 //break; //编译报错 //return false; //编译报错 return; } System.out.print(x + ","); }); } 输出: 5,6,7,8,9,10,
通过上述结果,我们可以得出如下结论:
在forEach循环中,continue和break在foreach循环中不允许使用;
在forEach循环中,return的效果等同于普通for循环里面的continue效果(结束本次循环继续下一次循环);
在forEach循环中,return语句不能直接把方法体给返回停止掉
因此,foreach虽然好用效率高,但也有它的局限性,各位可以根据自己的需求选择遍历方式。
foreach循环条件中,不用变量而改用方法的形式直接使用,方法会被调用多次吗?
例如下面代码:getDate被调用...会被打印输出多少次呢?
public static void main(String[] args) { System.out.println("================普通for循环:"); for (int i = 0; i < getData().size(); i++) { System.out.println(i); } System.out.println("================增强for循环:"); for (Integer i : getData()) { System.out.println(i); } System.out.println("================Java8提供的foreach循环:"); getData().forEach(System.out::println); } private static List<Integer> getData() { System.out.println("getDate被调用..."); var list = new ArrayList<Integer>(); list.add(10); list.add(20); list.add(30); return list; } 结果: 输出3次 输出1次 输出1次
有了这个结果,咱们以后使用for循环的时候,不需要定义的变量,就可以节省下来了,也显得我们对for循环原理更加的理解深入,高大上(装逼)的体现
其实原因很简单:我贴上.class文件的源码,一目了然,就不再解释了:
public static void main(String[] args) { System.out.println("================普通for循环:"); for(int i = 0; i < getData().size(); ++i) { System.out.println(i); } System.out.println("================增强for循环:"); Iterator var3 = getData().iterator(); while(var3.hasNext()) { Integer i = (Integer)var3.next(); System.out.println(i); } System.out.println("================Java8提供的foreach循环:"); List var10000 = getData(); PrintStream var10001 = System.out; System.out.getClass(); var10000.forEach(var10001::println); }
关于while循环和do…while循环的控制,和for循环的一模一样,因此这里不再做讨论了,各位可以自己在本机尝试一下。
最后再聊聊循环嵌套。最常见的就是for循环里面还有for循环,甚至3层或者更多层的循环嵌套。咱们先不讨论现实中允不允许这么去写代码,但从语法角度java是支持的,毕竟有些极其特殊的需求,还真得这么做。
关于循环嵌套,有时候我们希望通过continue、break等语句精准的控制具体的哪一层循环,从而达到我们的目的。java为了满足这种需求,支持了给循环**起别名(打标签)**的方式(for循环和while循环都可以其别名),基本语法也很简单,可看下面例子,打印9*9乘法表:
public static void main(String[] args) { a: for (int i = 1; i <= 9; i++) { b: for (int j = 1; j <= 9; j++) { System.out.print(j + "*" + i + "=" + (j * i) + "\t"); if(j >= i){ System.out.println(); continue a; //直接继续外层循环 } } } } 输出: 1*1=1 1*2=2 2*2=4 1*3=3 2*3=6 3*3=9 1*4=4 2*4=8 3*4=12 4*4=16 1*5=5 2*5=10 3*5=15 4*5=20 5*5=25 1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36 1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49 1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64 1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81
若不用for循环别名,需要这么些:
public static void main(String[] args) { for (int i = 1; i <= 9; i++) { for (int j = 1; j <= i; j++) { System.out.print(j + "*" + i + "=" + (i * j) + "\t"); } System.out.println(); } } 输出:同上
这种写法,可能for (int j = 1; j <= i; j++)这句话稍微有那么点难理解点。两种方式各有优劣,各位可以根据具体情况具体选择
3、使用场景
循环的使用场景无处不在,传统每一份逻辑代码。然后此文重点解惑了:foreach循环中的逻辑控制语句怎么使用的问题。希望掌握这个知识点后,遍历尽量的可以使用更加高效的foreach来控制代码结构,当然stream流式编程也是被推荐的。