【小家java】剖析for、while、foreach、标签循环语句的控制( break,continue,return )

相关阅读

【小家java】java5新特性(简述十大新特性) 重要一跃
【小家java】java6新特性(简述十大新特性) 鸡肋升级
【小家java】java7新特性(简述八大新特性) 不温不火
【小家java】java8新特性(简述十大新特性) 饱受赞誉
【小家java】java9新特性(简述十大新特性) 褒贬不一
【小家java】java10新特性(简述十大新特性) 小步迭代
【小家java】java11新特性(简述八大新特性) 首个重磅LTS版本


1、概述

java一共提供了3中循环语法:for循环(含增强for循环)、while循环、do…while循环。java8之后提供了基于stream的foreach循环,然后本文就针对于这几个循环,分别介绍一下循环控制语句:break,continue,return对循环体的影响。
特别隆重介绍:foreach循环中,如何停止本次循环和停止所有循环,因为stream的使用非常方便和广泛

2、栗子

最先开始,直接上主菜for循环,后面再介绍稍微简单的例子while循环等。
先来看一个最简单的循环体:

public static void main(String[] args) {
    for (int i = 0; i < 10; i++) {
        System.out.print(i + ",");
    }
}
输出:
0,1,2,3,4,5,6,7,8,9,

接下来,我们加入一些循环控制语句,看看效果:

public static void main(String[] args) {
   for (int i = 0; i < 10; i++) {
       if (i < 5) {
            continue;
        }
        System.out.print(i + ",");
    }
}
输出:
5,6,7,8,9,

public static void main(String[] args) {
    for (int i = 0; i < 10; i++) {
        System.out.print(i + ",");
        if (i < 5) {
            break;
        }
    }
}
输出:
0,

public static void main(String[] args) {
    for (int i = 0; i < 10; i++) {
        System.out.print(i + ",");
        if (i < 5) {
            return;
            //return false; //编译报错
            //return true; //编译报错
        }
    }
}
输出:
0,

从结果中很容易看出,for循环里的continue是结束本次循环继续下一次循环,break是结束当前for所有循环。而return表面上看效果和break一样,确实如此。但是,但是,但是需要注意:return其实是退出方法,它退出的层次是很高的,如果方法体只有一个for循环,效果一样。因此不同的场景,有时候用break,有时候用return,需要注意。

若只想退出for循环,并不想退出方法体,用break;
若退出for循环并且退出方法体,用return;

接下来简单说一下增强for循环(JDK5以后的新特性):

public static void main(String[] args) {
    List<String> lists = new ArrayList<>();
    lists.add("a");
    lists.add("b");
    for (String str : lists) {
        System.out.print(str + ",");
    }
}
输出:
a,b,

这里不介绍增强for的循环控制,我简要解释一下增强for其实只是个语法糖,大家就理解了。把我编译之后的.class文件的增前for贴出来,大家应该就不需要继续介绍了:

上面增强for编译过后代码如下:
public static void main(String[] args) {
     List lists = new ArrayList();
     lists.add("a");
     lists.add("b");
     
     Iterator var2 = lists.iterator();
     while(var2.hasNext()) {
         String str = (String)var2.next();
         System.out.print(str + ",");
     }
 }

我们发现增强for循环遍历和iterator遍历反编译后的字节码完全一样,所以增强for不用解释了,直接参考for循环和while循环的一些特点就行了




接下来,最重要的主菜登场:foreach循环。

随着java8的普及,基于流式的编程日益普及。它能使得代码的结构越发清晰并且效率也是大大的提升啊,因此我们平时在使用foreach循环的频率就越高了。但是大家或多或少都遇见类似头疼的问题:发现continue和break甚至return语法对foreach循环都不好使了

下面看看示例代码:

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流式编程也是被推荐的。

—-题后语—-

我的微信公众号也会持续推送技术干货,欢迎下方二维码扫码关注获取。
【小家java】剖析for、while、foreach、标签循环语句的控制( break,continue,return )_第1张图片
更多内容持续更新中,欢迎关注我的博客!
有任何问题,可以跟我留言讨论,欢迎指正,不胜感激。
有任何疑问,亦可扫码向我提我哟~

你可能感兴趣的:(享学Java)