🔄 07 流程控制之循环结构

更新日期:2026年5月
版权声明:本文为原创文章,转载请注明出处。© 2026 Java入门到精通系列



一、什么是循环

1.1 循环的概念

循环是一种重复执行某段代码的程序结构。它让我们可以用简短的代码实现重复操作,而不需要手动复制粘贴。

┌────────────────────────────────────────┐
│              循环的基本结构              │
├────────────────────────────────────────┤
│                                        │
│   ┌──────────┐                         │
│   │ 初始化表达式│                         │
│   └────┬─────┘                         │
│        │                               │
│   ┌────▼─────┐    false                │
│   │ 条件判断   │ ──────────► 循环结束      │
│   └────┬─────┘                         │
│     true│                              │
│   ┌────▼─────┐                         │
│   │ 循环体    │                         │
│   └────┬─────┘                         │
│        │                               │
│   ┌────▼─────┐                         │
│   │ 迭代表达式 │                         │
│   └────┬─────┘                         │
│        │                               │
│        └───────► 返回条件判断            │
│                                        │
└────────────────────────────────────────┘

1.2 循环的必要性

// 没有循环:打印1到100
System.out.println(1);
System.out.println(2);
System.out.println(3);
// ... 需要写100行代码!

// 使用循环:打印1到100
for (int i = 1; i <= 100; i++) {
    System.out.println(i);
}
// 只需要3行代码!

1.3 Java中的三种循环

循环类型 适用场景 特点
for 已知循环次数 语法简洁,最常用
while 未知循环次数,先判断后执行 可能一次都不执行
do-while 未知循环次数,先执行后判断 至少执行一次

二、for循环

2.1 基本语法

for (初始化表达式; 条件表达式; 迭代表达式) {
    // 循环体
}

执行顺序:

  1. 执行初始化表达式(只执行一次)
  2. 判断条件表达式,为true则继续,为false则退出
  3. 执行循环体
  4. 执行迭代表达式
  5. 回到第2步

2.2 代码示例

public class ForDemo {
    public static void main(String[] args) {
        // 示例1:打印1到10
        for (int i = 1; i <= 10; i++) {
            System.out.print(i + " ");
        }
        System.out.println(); // 换行
        // 输出:1 2 3 4 5 6 7 8 9 10
        
        // 示例2:打印1到10的和
        int sum = 0;
        for (int i = 1; i <= 10; i++) {
            sum += i; // sum = sum + i
        }
        System.out.println("1到10的和:" + sum); // 55
        
        // 示例3:打印偶数
        for (int i = 2; i <= 20; i += 2) {
            System.out.print(i + " ");
        }
        System.out.println();
        // 输出:2 4 6 8 10 12 14 16 18 20
        
        // 示例4:倒序打印
        for (int i = 10; i >= 1; i--) {
            System.out.print(i + " ");
        }
        System.out.println();
        // 输出:10 9 8 7 6 5 4 3 2 1
        
        // 示例5:求阶乘 5! = 5 * 4 * 3 * 2 * 1
        int n = 5;
        long factorial = 1;
        for (int i = 1; i <= n; i++) {
            factorial *= i;
        }
        System.out.println(n + "! = " + factorial); // 120
    }
}

2.3 for循环的变体

public class ForVariants {
    public static void main(String[] args) {
        // 变体1:多个初始化变量
        for (int i = 0, j = 10; i < j; i++, j--) {
            System.out.println("i=" + i + ", j=" + j);
        }
        
        // 变体2:省略部分表达式
        int i = 0;
        for (; i < 10; ) {  // 等价于 while (i < 10)
            System.out.print(i + " ");
            i++;
        }
        System.out.println();
        
        // 变体3:无限循环
        // for (;;) {
        //     System.out.println("无限循环");
        //     // 需要break来退出
        // }
        
        // 变体4:for循环作为while循环的替代
        int count = 0;
        for (; count < 5; ) {
            System.out.println("count = " + count);
            count++;
        }
    }
}

三、while循环

3.1 基本语法

while (条件表达式) {
    // 循环体
}

执行顺序:

  1. 判断条件表达式
  2. 为true则执行循环体
  3. 回到第1步
  4. 为false则退出循环

3.2 代码示例

public class WhileDemo {
    public static void main(String[] args) {
        // 示例1:打印1到10
        int i = 1;
        while (i <= 10) {
            System.out.print(i + " ");
            i++;
        }
        System.out.println();
        
        // 示例2:计算1到100的和
        int sum = 0;
        int num = 1;
        while (num <= 100) {
            sum += num;
            num++;
        }
        System.out.println("1到100的和:" + sum); // 5050
        
        // 示例3:猜数字游戏
        java.util.Scanner scanner = new java.util.Scanner(System.in);
        int target = 42; // 目标数字
        int guess;
        int attempts = 0;
        
        System.out.println("猜一个1-100之间的数字:");
        do {
            guess = scanner.nextInt();
            attempts++;
            
            if (guess > target) {
                System.out.println("太大了,再猜:");
            } else if (guess < target) {
                System.out.println("太小了,再猜:");
            } else {
                System.out.println("恭喜你猜对了!用了" + attempts + "次");
            }
        } while (guess != target);
        
        scanner.close();
    }
}

3.3 while循环的注意事项

public class WhileNotes {
    public static void main(String[] args) {
        // 注意1:避免死循环
        // 错误示例:忘记更新循环变量
        // int i = 0;
        // while (i < 10) {
        //     System.out.println(i);
        //     // 忘记 i++,死循环!
        // }
        
        // 正确示例
        int i = 0;
        while (i < 10) {
            System.out.print(i + " ");
            i++; // 确保循环变量更新
        }
        System.out.println();
        
        // 注意2:循环条件一开始就为false
        int x = 100;
        while (x < 10) {
            System.out.println("这行不会执行");
            x++;
        }
        System.out.println("while循环直接跳过");
    }
}

四、do-while循环

4.1 基本语法

do {
    // 循环体
} while (条件表达式);  // 注意这里有分号!

执行顺序:

  1. 执行循环体
  2. 判断条件表达式
  3. 为true则回到第1步
  4. 为false则退出循环

4.2 do-while的特点

do-while循环至少执行一次循环体,因为先执行后判断。

public class DoWhileDemo {
    public static void main(String[] args) {
        // 示例1:基本使用
        int i = 1;
        do {
            System.out.print(i + " ");
            i++;
        } while (i <= 10);
        System.out.println();
        // 输出:1 2 3 4 5 6 7 8 9 10
        
        // 示例2:至少执行一次
        int x = 100;
        do {
            System.out.println("这行会执行一次");
            x++;
        } while (x < 10);
        // 即使条件为false,循环体也执行了一次
        
        // 示例3:用户输入验证(do-while的经典应用)
        java.util.Scanner scanner = new java.util.Scanner(System.in);
        int number;
        
        do {
            System.out.print("请输入一个1-100之间的数字:");
            number = scanner.nextInt();
            
            if (number < 1 || number > 100) {
                System.out.println("输入无效,请重新输入!");
            }
        } while (number < 1 || number > 100);
        
        System.out.println("你输入的数字是:" + number);
        scanner.close();
    }
}

4.3 while和do-while的区别

public class WhileVsDoWhile {
    public static void main(String[] args) {
        int x = 100;
        
        // while:条件不满足,一次都不执行
        while (x < 10) {
            System.out.println("while: " + x);
            x++;
        }
        System.out.println("while循环执行了0次");
        
        // do-while:先执行后判断,至少执行一次
        x = 100;
        do {
            System.out.println("do-while: " + x);
            x++;
        } while (x < 10);
        System.out.println("do-while循环执行了1次");
    }
}

五、增强for循环(for-each)

5.1 基本语法

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

5.2 代码示例

public class ForEachDemo {
    public static void main(String[] args) {
        // 示例1:遍历数组
        int[] numbers = {1, 2, 3, 4, 5};
        
        // 传统for循环
        System.out.println("传统for循环:");
        for (int i = 0; i < numbers.length; i++) {
            System.out.print(numbers[i] + " ");
        }
        System.out.println();
        
        // for-each循环
        System.out.println("for-each循环:");
        for (int num : numbers) {
            System.out.print(num + " ");
        }
        System.out.println();
        
        // 示例2:遍历字符串数组
        String[] fruits = {"苹果", "香蕉", "橘子", "葡萄"};
        for (String fruit : fruits) {
            System.out.println("水果:" + fruit);
        }
        
        // 示例3:遍历集合
        java.util.List<String> names = java.util.Arrays.asList("张三", "李四", "王五");
        for (String name : names) {
            System.out.println("姓名:" + name);
        }
        
        // 示例4:计算数组元素之和
        int[] scores = {85, 92, 78, 96, 88};
        int sum = 0;
        for (int score : scores) {
            sum += score;
        }
        System.out.println("总分:" + sum);
        System.out.println("平均分:" + (sum / scores.length));
    }
}

5.3 for-each的限制

public class ForEachLimitation {
    public static void main(String[] args) {
        int[] numbers = {1, 2, 3, 4, 5};
        
        // 限制1:不能修改数组元素的值(基本类型)
        for (int num : numbers) {
            num = num * 2; // 这只是修改了局部变量,不影响原数组
        }
        System.out.println("数组未被修改:" + java.util.Arrays.toString(numbers));
        
        // 限制2:不能获取当前元素的索引
        // for (int num : numbers) {
        //     System.out.println("索引???"); // 无法知道当前是第几个元素
        // }
        
        // 限制3:只能单向遍历,不能跳过元素或反向遍历
        
        // 如果需要修改元素或使用索引,应该使用传统for循环
        for (int i = 0; i < numbers.length; i++) {
            numbers[i] = numbers[i] * 2; // 真正修改数组
        }
        System.out.println("数组已修改:" + java.util.Arrays.toString(numbers));
    }
}

六、break语句

6.1 break的作用

break用于立即终止当前循环或switch语句的执行。

6.2 代码示例

public class BreakDemo {
    public static void main(String[] args) {
        // 示例1:找到第一个能被7整除的数
        for (int i = 1; i <= 100; i++) {
            if (i % 7 == 0) {
                System.out.println("找到第一个能被7整除的数:" + i);
                break; // 找到后立即退出循环
            }
        }
        
        // 示例2:在数组中查找元素
        int[] numbers = {12, 25, 38, 47, 56, 69, 73};
        int target = 47;
        int index = -1;
        
        for (int i = 0; i < numbers.length; i++) {
            if (numbers[i] == target) {
                index = i;
                break;
            }
        }
        
        if (index != -1) {
            System.out.println("找到目标值" + target + ",索引为" + index);
        } else {
            System.out.println("未找到目标值");
        }
        
        // 示例3:break在while中的使用
        java.util.Scanner scanner = new java.util.Scanner(System.in);
        System.out.println("输入0退出循环:");
        
        while (true) { // 无限循环
            int input = scanner.nextInt();
            if (input == 0) {
                System.out.println("退出循环");
                break; // 跳出循环
            }
            System.out.println("你输入了:" + input);
        }
        
        scanner.close();
    }
}

6.3 带标签的break

当有多层嵌套循环时,可以使用标签来指定跳出哪一层循环。

public class LabeledBreakDemo {
    public static void main(String[] args) {
        // 示例:在二维数组中查找目标值
        int[][] matrix = {
            {1, 2, 3},
            {4, 5, 6},
            {7, 8, 9}
        };
        int target = 5;
        boolean found = false;
        
        // 使用标签
        outer: // 外层循环标签
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[i].length; j++) {
                if (matrix[i][j] == target) {
                    System.out.println("找到目标值" + target + ",位置:[" + i + "][" + j + "]");
                    found = true;
                    break outer; // 跳出外层循环
                }
            }
        }
        
        if (!found) {
            System.out.println("未找到目标值");
        }
        
        // 不使用标签的对比
        System.out.println("\n不使用标签:");
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[i].length; j++) {
                if (matrix[i][j] == target) {
                    System.out.println("找到目标值" + target + ",位置:[" + i + "][" + j + "]");
                    break; // 只跳出内层循环
                }
            }
            // 外层循环会继续执行
        }
    }
}

七、continue语句

7.1 continue的作用

continue用于跳过本次循环,继续执行下一次循环。

7.2 代码示例

public class ContinueDemo {
    public static void main(String[] args) {
        // 示例1:打印1-10中的奇数
        for (int i = 1; i <= 10; i++) {
            if (i % 2 == 0) {
                continue; // 跳过偶数
            }
            System.out.print(i + " ");
        }
        System.out.println();
        // 输出:1 3 5 7 9
        
        // 示例2:统计不及格人数
        int[] scores = {85, 42, 96, 55, 78, 38, 92};
        int failCount = 0;
        
        for (int score : scores) {
            if (score >= 60) {
                continue; // 跳过及格的成绩
            }
            failCount++;
        }
        System.out.println("不及格人数:" + failCount);
        
        // 示例3:continue在while中的使用
        int i = 0;
        while (i < 10) {
            i++;
            if (i % 3 == 0) {
                continue; // 跳过3的倍数
            }
            System.out.print(i + " ");
        }
        System.out.println();
        // 输出:1 2 4 5 7 8 10
    }
}

7.3 带标签的continue

public class LabeledContinueDemo {
    public static void main(String[] args) {
        // 示例:跳过特定的行和列
        System.out.println("打印矩阵(跳过第2行和第3列):");
        
        outer:
        for (int i = 1; i <= 4; i++) {
            for (int j = 1; j <= 4; j++) {
                if (i == 2) {
                    continue outer; // 跳过第2行
                }
                if (j == 3) {
                    continue; // 跳过第3列
                }
                System.out.print("[" + i + "," + j + "] ");
            }
            System.out.println();
        }
    }
}

八、嵌套循环

8.1 嵌套循环的概念

在一个循环体内再包含一个完整的循环,称为嵌套循环。

8.2 代码示例

public class NestedLoopDemo {
    public static void main(String[] args) {
        // 示例1:打印矩形
        System.out.println("===== 矩形 =====");
        for (int i = 0; i < 3; i++) {        // 行
            for (int j = 0; j < 5; j++) {    // 列
                System.out.print("* ");
            }
            System.out.println(); // 换行
        }
        // * * * * *
        // * * * * *
        // * * * * *
        
        // 示例2:打印直角三角形
        System.out.println("\n===== 直角三角形 =====");
        for (int i = 1; i <= 5; i++) {
            for (int j = 1; j <= i; j++) {
                System.out.print("* ");
            }
            System.out.println();
        }
        // *
        // * *
        // * * *
        // * * * *
        // * * * * *
        
        // 示例3:打印九九乘法表
        System.out.println("\n===== 九九乘法表 =====");
        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();
        }
        
        // 示例4:打印等腰三角形
        System.out.println("\n===== 等腰三角形 =====");
        int rows = 5;
        for (int i = 1; i <= rows; i++) {
            // 打印空格
            for (int j = 1; j <= rows - i; j++) {
                System.out.print(" ");
            }
            // 打印星号
            for (int k = 1; k <= 2 * i - 1; k++) {
                System.out.print("*");
            }
            System.out.println();
        }
        //     *
        //    ***
        //   *****
        //  *******
        // *********
    }
}

8.3 嵌套循环的执行次数

public class NestedLoopCount {
    public static void main(String[] args) {
        // 外层循环n次,内层循环m次,总共执行n×m次
        int count = 0;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 4; j++) {
                count++;
            }
        }
        System.out.println("总共执行了" + count + "次"); // 12
        
        // 注意:内层循环的次数可能随外层变量变化
        count = 0;
        for (int i = 1; i <= 5; i++) {
            for (int j = 1; j <= i; j++) {
                count++;
            }
        }
        System.out.println("变长内层循环执行了" + count + "次"); // 15 (1+2+3+4+5)
    }
}

九、循环实战练习

练习1:求素数

public class PrimeNumber {
    public static void main(String[] args) {
        System.out.println("100以内的素数:");
        
        for (int num = 2; num <= 100; num++) {
            boolean isPrime = true;
            
            // 判断是否为素数
            for (int i = 2; i <= Math.sqrt(num); i++) {
                if (num % i == 0) {
                    isPrime = false;
                    break;
                }
            }
            
            if (isPrime) {
                System.out.print(num + " ");
            }
        }
        System.out.println();
    }
}

练习2:斐波那契数列

public class Fibonacci {
    public static void main(String[] args) {
        int n = 20; // 打印前20个
        long[] fib = new long[n];
        
        fib[0] = 0;
        fib[1] = 1;
        
        System.out.println("斐波那契数列前" + n + "项:");
        System.out.print(fib[0] + " " + fib[1] + " ");
        
        for (int i = 2; i < n; i++) {
            fib[i] = fib[i - 1] + fib[i - 2];
            System.out.print(fib[i] + " ");
        }
        System.out.println();
    }
}

练习3:水仙花数

public class NarcissisticNumber {
    public static void main(String[] args) {
        System.out.println("三位数中的水仙花数:");
        // 水仙花数:各位数字立方和等于该数本身
        // 例如:153 = 1^3 + 5^3 + 3^3
        
        for (int num = 100; num <= 999; num++) {
            int ge = num % 10;        // 个位
            int shi = num / 10 % 10;  // 十位
            int bai = num / 100;      // 百位
            
            if (ge * ge * ge + shi * shi * shi + bai * bai * bai == num) {
                System.out.println(num + " = " + bai + "³ + " + shi + "³ + " + ge + "³");
            }
        }
    }
}

练习4:打印菱形

public class Diamond {
    public static void main(String[] args) {
        int n = 5; // 上半部分行数
        
        // 上半部分
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n - i; j++) {
                System.out.print(" ");
            }
            for (int k = 1; k <= 2 * i - 1; k++) {
                System.out.print("*");
            }
            System.out.println();
        }
        
        // 下半部分
        for (int i = n - 1; i >= 1; i--) {
            for (int j = 1; j <= n - i; j++) {
                System.out.print(" ");
            }
            for (int k = 1; k <= 2 * i - 1; k++) {
                System.out.print("*");
            }
            System.out.println();
        }
    }
}

十、常见面试题

面试题1:for、while、do-while的区别?

答案

循环类型 特点
for 适合已知循环次数,语法紧凑
while 适合未知循环次数,先判断后执行,可能一次都不执行
do-while 适合未知循环次数,先执行后判断,至少执行一次

面试题2:break和continue的区别?

答案

  • break:立即终止整个循环,跳出循环体
  • continue:跳过本次循环的剩余代码,继续下一次循环

面试题3:如何在嵌套循环中跳出外层循环?

答案:使用带标签的break语句:

outer:
for (...) {
    for (...) {
        if (条件) {
            break outer; // 跳出外层循环
        }
    }
}

面试题4:以下代码的输出是什么?

for (int i = 0; i < 5; i++) {
    if (i == 3) {
        continue;
    }
    System.out.print(i + " ");
}

答案0 1 2 4(跳过了3)


十一、总结与预告

本节要点回顾

知识点 核心内容
for循环 适合已知循环次数
while循环 适合未知循环次数,先判断后执行
do-while循环 先执行后判断,至少执行一次
for-each循环 简化数组和集合遍历
break 终止整个循环
continue 跳过本次循环
嵌套循环 循环体内嵌套循环
标签 在嵌套循环中控制break/continue

🤔 互动问题

  1. 如何选择使用哪种循环结构?
  2. while(true)和for(;;)有什么区别?
  3. 循环中的常见bug有哪些?如何避免?

📖 下篇预告

下一篇我们将学习数组详解——一维数组、二维数组、Arrays工具类以及常见算法(排序、查找),这是Java中非常重要的数据结构!


📚 参考资料


💡 学习建议:循环是编程的核心,建议多做练习题来熟练掌握。特别注意避免死循环,以及break和continue的正确使用场景。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐