欢迎光临
我们一直在努力

11.【Java】流程控制之循环

摘要: 本文系统讲解了 Java 中循环结构的核心概念与使用方法,涵盖 while、do-while、for 及增强 for 循环的语法、执行流程和适用场景,并深入介绍了 break、continue 控制语句、循环嵌套以及常见陷阱。通过丰富的代码示例和综合的猜数字游戏实战,帮助初学者快速掌握循环这一实现代码重复执行的关键技术,为后续学习打下坚实基础。

关键词: Java 循环, while 循环, for 循环, break 和 continue, 循环嵌套


我们学会了变量来存储数据,学会了运算符来处理数据,还学会了条件判断来让程序做决策。但你会发现,如果程序只会从上到下执行一次,那么很多事情都做不了。

比如,你想打印 100 遍“我爱你”,难道要写 100 行 System.out.println("我爱你"); 吗?当然不是。如果让你计算 1 到 100 的总和,难道要写 1+2+3+…+100 吗?那样既不现实,也毫无意义。

我们需要一种能力:让一段代码重复执行多次,直到某个条件不再满足为止。这就是循环(Loop)。

循环是程序设计中最重要的控制结构之一,它让程序具备了“批量处理”的能力。Java 提供了三种循环结构:while、do-while 和 for。另外,还有一种专门遍历集合的“增强 for 循环”(for-each)。我们来逐一认识它们。


1. while 循环 —— 先判断,再执行

while 循环是最基本的一种。它的语法是:

while (条件) {
// 循环体:当条件为 true 时,重复执行这里的代码
}

执行流程很简单:

  • 判断条件是否为 true。
  • 如果是,执行一次循环体。
  • 执行完后再回到第 1 步,继续判断。
  • 如果条件为 false,跳出循环,继续执行后面的代码。
  • 如果条件一开始就是 false,循环体一次都不会执行。

    看一个经典例子:打印 1 到 5 的数字。

    int i = 1; // 初始化计数器
    while (i <= 5) { // 条件:i 小于等于 5
    System.out.println(i);
    i++; // 更新计数器,否则会死循环
    }
    System.out.println("循环结束!");

    输出:

    1
    2
    3
    4
    5
    循环结束!

    这里我们用了三个要素:

    • 初始化:int i = 1;
    • 条件:i <= 5
    • 更新:i++

    缺少任何一个,循环都可能出问题。尤其是如果忘了 i++,条件永远为真,程序会一直打印 1,直到你强行终止它——这就是死循环(无限循环)。写循环时一定要确保条件最终会变为 false。

    while 常用于“不确定次数”的循环

    比如,你让用户输入一个正数,如果输入的不是正数,就一直提示重新输入。你事先不知道用户会输错多少次,但循环可以一直问下去。

    Scanner scanner = new Scanner(System.in);
    int number;
    System.out.print("请输入一个正数:");
    number = scanner.nextInt();
    while (number <= 0) {
    System.out.print("输入无效,请重新输入一个正数:");
    number = scanner.nextInt();
    }
    System.out.println("你输入了:" + number);


    2. do-while 循环 —— 先执行,再判断

    do-while 和 while 非常相似,唯一的不同是:do-while 先执行一次循环体,然后再判断条件。所以至少会执行一次。

    语法:

    do {
    // 循环体
    } while (条件);

    注意最后有一个分号 ;,别漏掉。

    把上面的“输入正数”的例子用 do-while 改写,会更自然,因为我们至少需要询问一次。

    Scanner scanner = new Scanner(System.in);
    int number;
    do {
    System.out.print("请输入一个正数:");
    number = scanner.nextInt();
    } while (number <= 0);
    System.out.println("你输入了:" + number);

    这样写,代码更紧凑,不需要在循环前重复写一次输入语句了。

    什么时候用 while,什么时候用 do-while?

    • 如果可能一次都不执行,用 while。
    • 如果至少需要执行一次(比如菜单交互、输入验证),用 do-while。

    3. for 循环 —— 计数循环的“集大成者”

    for 循环是最常用的循环结构,尤其适合已知循环次数的场景。它把“初始化”、“条件”、“更新”三个要素整齐地写在一行,结构清晰。

    语法:

    for (初始化; 条件; 更新) {
    // 循环体
    }

    执行顺序:

  • 执行初始化(只执行一次)。
  • 判断条件,如果为 true 则继续,为 false 则退出。
  • 执行循环体。
  • 执行更新。
  • 回到第 2 步。
  • 看一个打印 1 到 5 的例子:

    for (int i = 1; i <= 5; i++) {
    System.out.println(i);
    }

    输出一样。这里 int i = 1 只在循环开始时执行一次,i++ 在每次循环体执行完后执行。变量 i 的作用域仅限于 for 循环内部,循环结束后 i 就不可用了(除非你在外部提前定义)。

    更复杂的 for 用法
    • 可以初始化多个变量:用逗号分隔,但类型必须相同。
    • 更新部分也可以多条语句:用逗号分隔。
    • 三个部分都可以省略,但分号不能省。比如 for (;;) 就是一个死循环(相当于 while(true))。

    // 同时初始化 i 和 j
    for (int i = 0, j = 10; i < j; i++, j) {
    System.out.println("i=" + i + ", j=" + j);
    }
    // 输出:i=0, j=10; i=1, j=9; i=2, j=8; i=3, j=7; i=4, j=6

    计算 1 到 100 的总和

    int sum = 0;
    for (int i = 1; i <= 100; i++) {
    sum += i; // sum = sum + i
    }
    System.out.println("1到100的总和是:" + sum); // 5050


    4. 增强 for 循环(for-each) —— 专为遍历而生

    在 JDK 5 中引入了一种更简洁的循环形式,专门用来遍历数组或集合(我们后面会详细学)。它不需要索引,也不需要手动维护计数器,语法简单:

    for (元素类型 变量名 : 数组或集合) {
    // 循环体
    }

    比如遍历一个整数数组:

    int[] numbers = {10, 20, 30, 40, 50};
    for (int num : numbers) {
    System.out.println(num);
    }

    它会依次把数组中的每个元素赋值给 num,然后执行循环体。你不用关心索引,也不用担心越界。

    不过,增强 for 循环不能修改数组/集合的元素(因为它拿到的只是一个副本),而且在需要索引的情况下(比如要修改某个位置的值)也不适用,此时还得用普通的 for。

    我们在第四阶段学习集合时会大量使用增强 for,现在先留个印象。


    5. break 和 continue —— 跳出或跳过

    在循环体中,有时我们需要提前结束循环,或者跳过当前这次迭代,进入下一次。这时就需要 break 和 continue。

    • break:立即终止整个循环,跳出循环体,执行循环后面的代码。
    • continue:立即结束本次迭代,跳过本轮循环体中剩余的代码,直接进入下一次迭代(对于 for 循环,会先执行更新部分,再判断条件)。

    // break 示例:找到第一个能被 7 整除的数
    for (int i = 1; i <= 100; i++) {
    if (i % 7 == 0) {
    System.out.println("第一个能被7整除的数是:" + i);
    break; // 找到就跳出循环
    }
    }
    // 输出 7

    // continue 示例:打印 1 到 10 之间的奇数
    for (int i = 1; i <= 10; i++) {
    if (i % 2 == 0) {
    continue; // 偶数跳过,不打印
    }
    System.out.println(i);
    }
    // 输出 1,3,5,7,9

    带标签的 break 和 continue(了解即可)

    在嵌套循环中,break 默认只跳出当前最内层循环。如果你想从内层循环直接跳出外层循环,可以使用标签(label):

    outer: // 标签,后面跟冒号
    for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
    if (i == 1 && j == 1) {
    break outer; // 直接跳出外层循环
    }
    System.out.println("i=" + i + ", j=" + j);
    }
    }
    // 只会打印 i=0,j=0; i=0,j=1; i=0,j=2; i=1,j=0

    虽然带标签的 break 有用,但过多的嵌套和跳转会降低代码可读性。一般尽量通过设计循环条件来避免复杂跳转。


    6. 循环嵌套 —— 循环里面套循环

    一个循环的循环体内包含另一个循环,这叫嵌套循环。最常见的场景是打印二维图形、处理矩阵等。

    比如打印一个 5 行 5 列的星号矩形:

    for (int row = 1; row <= 5; row++) {
    for (int col = 1; col <= 5; col++) {
    System.out.print("* ");
    }
    System.out.println(); // 每行结束换行
    }

    输出:

    * * * * *
    * * * * *
    * * * * *
    * * * * *
    * * * * *

    稍微改一下,打印一个直角三角形:

    for (int row = 1; row <= 5; row++) {
    for (int col = 1; col <= row; col++) {
    System.out.print("* ");
    }
    System.out.println();
    }

    输出:

    *
    * *
    * * *
    * * * *
    * * * * *

    嵌套循环时,外层循环控制“行数”或“轮数”,内层循环控制“每行的细节”。理解这个层次关系是关键。


    7. 循环中的常见陷阱

    • 死循环:条件永远为真。比如 while (true) 或 for (;;),或者忘了更新变量。一定要确保循环能结束。
    • 差一错误(Off-by-one):循环条件中的 < 和 <= 搞混,导致多一次或少一次。比如要循环 5 次,用 i < 5(0~4)还是 i <= 5(0~5)?要清楚。
    • 在循环内改变循环变量的值:如果不小心在循环体里修改了循环变量,可能导致意外行为。
    • break 和 continue 的滥用:它们会让代码逻辑变得不那么直观,尽量用循环条件本身来控制流程,而不是依赖跳转。

    8. 综合示例 —— 猜数字游戏

    我们把今天学的循环和条件判断结合起来,写一个有趣的“猜数字”游戏:程序随机生成一个 1~100 的整数,用户输入猜测,程序提示“大了”或“小了”,直到猜中为止,并统计猜的次数。

    package com.example.demo;

    import java.util.Scanner;
    import java.util.Random; // Random 类用于生成随机数

    /**
    * 猜数字游戏:演示 while 循环、break、条件判断
    */

    public class GuessNumber {
    public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    Random random = new Random();

    // 生成 1~100 的随机整数
    int target = random.nextInt(100) + 1; // nextInt(100) 返回 0~99,+1 变成 1~100
    int guess;
    int attempts = 0;
    boolean guessed = false;

    System.out.println("===== 猜数字游戏 =====");
    System.out.println("我已经想好了一个 1~100 之间的整数,猜猜看吧!");

    // 使用 while 循环,直到猜对为止
    while (!guessed) {
    System.out.print("请输入你的猜测:");
    guess = scanner.nextInt();
    attempts++;

    if (guess < target) {
    System.out.println("太小了,再大一点!");
    } else if (guess > target) {
    System.out.println("太大了,再小一点!");
    } else {
    System.out.println("恭喜你,猜对了!答案就是 " + target);
    System.out.println("你一共猜了 " + attempts + " 次。");
    guessed = true; // 设置标志,退出循环
    // 也可以用 break,但用标志让代码更清晰
    }
    }

    scanner.close();
    }
    }

    这个程序综合了我们学过的变量、运算符、条件判断和循环,是一个很好的阶段性练习。


    9. 循环的选择指南

    场景推荐循环
    已知确切的循环次数(如遍历数组、计数) for
    根据条件决定是否继续,可能一次都不执行 while
    至少需要执行一次(如输入验证、菜单) do-while
    遍历数组或集合的所有元素 增强 for(for-each)

    今天的总结

    今天我们解锁了程序的“批量处理”能力:

    • while:先判断后执行,可能为 0 次。
    • do-while:先执行后判断,至少为 1 次。
    • for:集初始化、条件、更新于一体,适合计数循环。
    • 增强 for:简洁遍历数组/集合。
    • break 和 continue:控制循环的提前退出或跳过。
    • 嵌套循环:处理多维问题。

    循环是程序中最常见的结构之一,几乎每个有用的程序都离不开它。掌握好循环,你就能写出更加强大、灵活的程序。


    动手试试

  • 用 for 循环计算 1 到 100 之间的奇数和、偶数和,并分别打印。
  • 用嵌套循环打印一个 9×9 乘法表(格式整齐)。
  • 改写猜数字游戏:增加一个限制,最多猜 7 次,如果 7 次都没猜对,提示“游戏结束,正确答案是 xxx”并退出(用 break 或条件判断)。
  • 写一个程序,从用户输入一个正整数 n,输出它的所有因数(能整除 n 的数)。比如输入 12,输出 1,2,3,4,6,12。
  • 循环非常强大,但也很容易写出 bug。多练习几次,你就能驾驭它了。

    我们下一篇会讲方法——如何把代码组织成可复用的“积木块”,让你的程序更有条理。

    我们下一篇见。😃

    📌 获取本系列示例代码请访问 GitCode。

    赞(0)
    未经允许不得转载:171主机测评 » 11.【Java】流程控制之循环
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址