Java循环教程:掌握for、while和do-while循环的用法与技巧

引言

在编程中,编写重复性任务非常常见。一种选择是根据需要编写相同或相似的代码,以便重复执行代码块。然而,这种方法远非完美,因为它会创建大量难以阅读和维护的重复代码。一个更好的选择是使用循环。

循环是控制重复程序流程的结构。典型的循环包含两个部分:一个布尔控制条件和一个代码块。当条件为真时,代码块会被执行,或者直到条件变为假为止。布尔条件会在每次运行代码块时重新评估。退出循环的条件对于每种类型的循环是不同的,这将在本教程中详细学习。

Java 中主要有两种循环类型:while 循环和 for 循环。循环的类型取决于其语法和逻辑。while 循环依赖于布尔条件,只要条件为真,代码块就会重复执行。for 循环也会重复执行代码块,但其循环条件通常取决于整数变量的增加或减少。当这个变量达到特定的目标值时,循环将会中断。

在本教程中,您将使用 while 循环和 for 循环来创建重复性任务,并了解每种循环的优缺点。

前提条件

要按照此教程进行操作,您需要以下内容:

  • 一个可以执行 Java 程序的开发环境,以便跟随示例进行操作。要在您的本地机器上进行设置,您需要:在您的机器上安装 Java(版本 11 或更高),并包含 Java 开发工具包(JDK)提供的编译器。对于 Ubuntu 和 Debian 用户,请遵循我们教程《如何在 Ubuntu 22.04 上使用 Apt 安装 Java》中选项 1 的步骤。对于包括 Mac 和 Windows 在内的其他操作系统,请遵循 Java 安装的下载选项。为了编译和运行代码示例,本教程使用 Java Shell(也称为 JShell),它是一个从命令行运行的读-求值-打印循环(REPL)。要开始使用 JShell,请查阅《JShell 入门指南》。
  • 熟悉 Java 和面向对象编程,您可以在我们的教程《如何在 Java 中编写您的第一个程序》中找到相关内容。
  • 理解 Java 数据类型,这在我们的教程《理解 Java 中的数据类型》中有所讨论。

while 循环操作

while 循环监控一个通用的布尔条件语句。例如,这个条件语句可以验证两个整数变量是否相等,或者两个对象是否相同、相关、非空,或者任何其他可以通过编程检查的情况。实际上,可以使用任何布尔语句,这也是为什么 while 循环如此强大且广泛使用的原因。

在本节中,您将使用 while 关键字在 Java 中创建您的第一个编程循环。您将使用一个 int 变量来控制循环。这个 int 变量将被命名为 x,并具有初始值 3。只要 x 大于 0,循环将继续执行一段代码块。在这个代码块中,x 的值将被打印出来,并且最重要的是,每次执行后都会进行后递减(使用 -- 运算符)。这个后递减操作使得当前的循环在几次执行后结束。如果没有这个操作,循环将会无限继续。

信息:为了跟随本教程中的示例代码,请通过运行 jshell 命令在您的本地系统上打开 JShell 工具。然后,您可以在 jshell> 提示后粘贴、复制或编辑示例,并按 ENTER 键执行。要退出 jshell,请键入 /exit。为了测试这段代码,请将下面的行粘贴到 jshell 中。

  1. int x = 3;
  2. while (x > 0) {
  3. System.out.println("x is " + x--);
  4. }

在第一行,您定义了变量 x

循环从第2行开始,使用 while 关键字。条件语句 (x > 0) 控制循环。它比较 x 是否大于 0。之后是开括号 {,表示代码块的开始。只要条件为真 (x > 0),该代码块将被重复执行。

代码块中,第3行的 System.out.println("x is " + x--); 语句使用 println() 方法打印出 x 的当前值。(查看我们的《如何在 Java 中编写您的第一个程序》教程,了解更多关于 System.out.println 语句的内容。)在 println() 的参数中,使用 x-- 代码对 x 进行后递减 1 操作。每执行一次,x 减少 1。

代码块在最后一行以右括号 } 结束。这也是循环的结束处。

当您在 jshell 中运行此代码时,将会打印出以下的输出。

输出

x ==> 3
x is 3
x is 2
x is 1

第一行确认了 x 已经收到了值为 3。在接下来的几行中,x 的值被打印了三次,每次减少 1。只有三次迭代中,x 的值分别为 3、2 和 1。当 x 达到 0 时,循环终止,因为条件语句 x > 0 不再满足。此时,循环退出,并且不再打印任何内容。

前面的例子是创建循环的常见方法。循环的意图明确,退出条件也很简单:x > 0。理论上,您可以通过添加额外的变量和比较(如 x > 0y < 0)来使条件更复杂,但从代码规范的角度来看,这不被认为是最佳实践。复杂的条件使代码难以跟踪和理解,并且提供的价值微乎其微,如果有的话。

do-while 循环

do-while 循环比 while 循环不太流行,但仍然被广泛使用。do-while 循环与 while 循环很相似,但在一个关键方面有所不同:代码块先执行,然后再评估循环条件。

作为提醒,当循环条件不满足时,while 循环首先评估条件,可能永远不会执行代码块。然而,在 do-while 循环中,代码块至少执行一次,然后再评估循环控制条件。如果条件为真,循环将继续进行额外的迭代,直到条件不再为真。因此,在需要询问问题并仅在得到正确答案时才终止循环的场景中,do-while 循环非常有用。

在本节中,您将创建一个与前一节中的 while 循环类似的 do-while 循环。整数变量将被称为 x,并且初始值为 3。然而,这一次条件被颠倒(x < 0),并且代码块将在评估条件之前执行。

在终端打开 jshell 并添加 do-while 循环。

  1. int x = 3;
  2. do {
  3. System.out.println("x is " + x--);
  4. } while (x < 0);

代码与前一节中的 while 循环有一些相似之处。首先,变量 x 再次被赋值为 3。

在第2行,循环以关键字 do 和代码块的开括号 { 开始。在第3行,使用 println() 方法打印 x 的值。使用 println() 方法时,还使用后减操作符 -- 来递减 x 的值。

在代码块的最后一行是闭合括号 },之后是带有条件语句 (x < 0)while 关键字。这是与之前的 while 循环不同的地方。在这里,条件被颠倒了:x 应该小于 0。在之前的例子中,条件要求 x 大于 0。这个变化表明即使条件永远不满足,代码块也会运行一次。

当您在 jshell 中运行这段代码时,将会打印出以下输出。

输出

x ==> 3
x is 3

第一行确认了 x 的值是 3。第二行打印 x 是 3。这是 do-while 循环的特点:即使条件 (x < 0) 不满足,代码块仍然会执行至少一次。这种无条件执行可能并不总是需要的,所以在使用 do-while 循环时需要谨慎。由于这个注意事项,do-while 循环并不经常使用。

for 循环

这是文章《如何在Java中使用循环》的第2部分(共3部分)。

另一种循环结构是 for 循环。它也用于根据条件重复运行一段代码,但比 while 循环有更多的选项。在循环控制条件中,你可以添加临时变量,定义控制条件,并改变临时变量的值。这样,你将所有控制循环的因素绑定在一起,减少了漏掉某些东西或犯错误的可能性。这使你的代码更易于理解和整洁。当你想在代码中遵循更严格的风格时,for 循环更适合使用。

这是一个典型的 for 循环:

  1. for (int x = 3; x > 0; x–) {
  2. System.out.println(“x is “ + x);
  3. }

 

循环以第一行的 for 关键字开始。括号内的条件语句由三个部分组成。

  • int x = 3 定义了一个变量 (x)。在这里定义一个临时变量很方便,因为它们只在循环中需要,所以将它们集成到循环中是有意义的。相比之下,当你使用 while 循环时,你必须在循环之前单独声明变量。
  • x > 0 是代码块执行必须满足的条件。在这种情况下,x 必须大于 0。这部分类似于 while 循环控制语句,后者只包含要评估的条件。
  • x-- 是每次成功迭代时执行的操作。在这种情况下,后置递减操作在每次成功执行后减少 x 的值。

第2行的 System.out.println("x is " + x); 语句使用 println() 方法打印出 x 的值。它接收到的是 x 的原始值。相比之下,在 while 循环中你使用了 println() 方法来操作 x 的值。在这种情况下是不必要的,因为后缀递减操作已经在条件语句的第三部分中处理了:x--

第三行用闭合括号 } 结束了代码块和整个循环结构。

当你在 jshell 中运行此代码时,会打印出以下输出:

输出
x is 3
x is 2
x is 1

输出确认代码块已执行三次。第一次,x 的值为3。第二次,x 为2,第三次,x 为1。第三次后,x 变为0,循环退出,而代码块(打印 x 的值)未被执行。

这个 for 循环达到了与 while 循环相同的结果。从性能和资源使用的角度来看,应该没有什么差异,所以更多是个人偏好来选择使用哪种循环。然而,如果迭代次数是已知的,通常推荐使用 for 循环,因为它可以使你更清晰地跟踪代码。

for-each 循环

for-each 循环与其他循环相似,但其优点在于专门为尽可能少的代码遍历一组数值而设计。只要你有一组数值,就无需跟踪它们的数量或跟随迭代过程,就可以遍历它们。for-each 循环会确保如果组中存在数值,它们将被逐个提取并呈现给你。

大多数编程语言都有一个方便的快捷方式用于 for-each 循环。在 Java 中,没有专门的 for-each 关键字,而是使用 for 关键字。然而,for-each 条件语句与常见的 for 循环不同,你将在下面发现。

要使用 for-each 循环,你需要使用一组值,并且数组非常适合这个目的。数组是一个包含相同类型值的对象。在接下来的示例中,你将使用包含 int 值的数组。

将以下代码添加到 jshell 中用于 for-each 循环:

  1. int[] numbers = {0, 1, 2};
  2. for (int x: numbers) {
  3. System.out.println(x);
  4. }

 

第一行,你创建了一个整数数组,包含三个整数(0、1和2)。

for-each 循环从第2行的 for 关键字开始。然后,您定义一个临时变量 int x,接着是一个冒号。冒号用作 for-each 操作的快捷方式。(for-each 循环语句是独特的,因为这是 Java 中唯一使用冒号的地方。)冒号后面是一组值,例如一个数组。

for-each 循环语句之后是代码块,在这里将为 numbers 数组的每个值执行该代码块。在这种情况下,System.out.println(x) 语句将使用 println() 方法打印 x 的值,该方法将引用 numbers 数组的每个值。

当您在 jshell 中运行上述代码时,将打印以下输出。

输出
numbers ==> int[3] { 0, 1, 2 }
0
1
2

第一行确认了一个名为 numbers 的数组已经定义,其中包含了数值0、1和2。以下的行打印出数组的值,每个值占据一行:0、1和2。

尽管使用其他循环主要是个人选择的问题,但 for-each 循环是在一组值上迭代的事实标准。可以使用 forwhile 循环创建自己的替代 for-each 循环,但这并不值得付出很大努力,并且需要对数据结构有深入的理解。

无限循环

无限循环是指那些永远不会终止的 for 循环或 while 循环。当控制条件始终为真时,它们变成无限循环。

这是一个常见的无限循环的示例:

  1. while (true) {
  2. System.out.println(“This will print forever.”);
  3. }

 

第一行看起来像是一个典型的 while 循环,但是不同于 x > 0 这样的条件,它只有 true 这个值。在这种情况下,当需要评估控制条件时,总是直接返回 true。在这种情况下,循环没有退出条件,所以它会永远继续执行。第二行包含了 System.out.println("This will print forever."); 语句;它会使用 println() 方法打印文本“This will print forever”。

当你在 jshell 中运行上述代码时,下面的输出将会打印,直到你终止代码。准备使用键盘组合 CTRL+C 快速终止它,或者直接关闭终端。否则,它将无休止地继续运行。

输出

只显示前两次重复,但这个输出将会一直继续,直到你按下CTRL+C手动终止它。

通过无限循环的示例,可以明显看出在布尔语句中放置一个真值是有意创造这样一个循环的。这种循环在过去很受欢迎,可能会在遗留项目中存在。您仍然可以创建这样的无限循环,但是有更好的方法来创建持续运行的任务,例如使用定时器任务。定时器任务更加高级并提供更多选项,因此更受推荐。

很不幸,有时无限循环并非故意的。你可能会犯错,导致无限循环。请考虑以下代码:

  1. int x = 3;
  2. while (x > 0) {
  3. System.out.println("x is " + x);
  4. }

上面的代码和教程中的第一个示例非常相似。在第一行,你定义了一个变量x,其值为3。

在第2行中出现了while关键字和控制条件,它表示循环应该在x > 0为真时继续。

第3行的System.out.println("x is " + x);语句使用println()方法打印x的值。然而,与本教程第一部分中的while循环示例相比,该循环没有在三次运行后结束,当前示例中也没有后缀递减操作。因此,当您在jshell中运行此循环时,您将会得到以下连续的输出。

Output
x is 3
x is 3
...

除非你使用CTRL+C终止循环,否则这些代码行将无休止地重复执行。这种意外的无限循环很危险,因为可能导致程序崩溃或超载运行程序的机器。这就是为什么在创建循环时应该小心,并确保存在可行的终止条件路径。在当前的例子中,你应该确保每次循环都减少x的值,以满足循环退出条件x > 0

结论

在本教程中,你使用循环结构来创建重复任务。你学会了在何时适合使用whilefor循环,并撰写了一些相关的代码示例。你还学习了编写整洁代码的最佳实践,以及如何避免循环相关的常见陷阱。

想了解更多关于Java的内容,请查看我们的Java编码系列教程。

bannerAds