Java各版本新特性详解:从Java5到Java11的十大重要更新与迭代
【小家java】Java5新特性(十大新特性简介)重要的飞跃

【小家java】java6新特性(简述十大新特性)鸡肋升级
[Xiaojiajava] java7新特性(八个新特性简述)不温不火
【小家java】java8新特性(简述十大新特性),备受好评
[Xiaojiajava] Java 9新特性(简述十大新特性),评价褒贬不一
【Xiaojiajava】Java10新特性(十大新特性简述)小步迭代
[Xiaojiajava] java11新特性(八个新特性简介) 第一个主要LTS版本
1. 概述
Java 总共提供了 3 种循环语法:for 循环(包括增强的 for 循环)、while 循环和 do...while 循环。 Java 8 之后,提供了基于流的 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,
这里就不介绍enhanced for的循环控制了。我简单解释一下,enhanced 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循环遍历和迭代器遍历的反编译字节码是一模一样的,所以增强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使用方便且高效,但它也有其局限性。您可以根据自己的需要选择遍历方式。
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循环,甚至三层以上的循环嵌套。我们先不讨论现实中是否允许这样写代码,但从语法上来看,Java是支持的。毕竟有一些极其特殊的需求,所以我们确实不得不这样做。
关于循环嵌套,有时候我们想通过 continue、break 等语句来精确控制使用哪一层循环来达到我们的目的。为了满足这种需求,Java支持对for循环进行别名(标记)的方法(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