2. java循环控制

Java Scanner 类 & 循环控制语句笔记

参考: CSDN - Shane_Cheng0202


一、Scanner 类(用户交互输入)

1.1 基本使用步骤

// 1. 导入 Scanner 类
import java.util.Scanner;

public class Demo {
    public static void main(String[] args) {
        // 2. 创建 Scanner 对象,System.in 表示从控制台读取
        Scanner sc = new Scanner(System.in);

        // 3. 接收用户输入
        System.out.print("请输入你的名字: ");
        String name = sc.nextLine();

        System.out.println("你好, " + name);

        // 4. 使用完毕后关闭
        sc.close();
    }
}

1.2 常用方法一览

方法 返回类型 说明
next() String 读取下一个单词(遇空白字符结束)
nextLine() String 读取整行(遇换行符结束,可包含空格)
nextInt() int 读取整数
nextDouble() double 读取双精度浮点数
nextFloat() float 读取单精度浮点数
nextLong() long 读取长整数
nextByte() byte 读取字节
nextShort() short 读取短整数
nextBoolean() boolean 读取布尔值
hasNext() boolean 是否还有下一个单词可读
hasNextLine() boolean 是否还有下一行可读
hasNextInt() boolean 下一个 token 是否为 int
hasNextDouble() boolean 下一个 token 是否为 double

1.3 next() vs nextLine() 的常见坑

Scanner sc = new Scanner(System.in);

// 常见错误: nextInt() 后直接调用 nextLine()
System.out.print("请输入年龄: ");
int age = sc.nextInt();

System.out.print("请输入姓名: ");
String name = sc.nextLine();
// ⚠️ name 直接读到了上次遗留的换行符,结果是空字符串!

// 输出: 年龄=18, 姓名=      ← 姓名根本没让你输入!

原因: nextInt() 只读取数字,输入时按下的换行符 `` 残留在缓冲区,紧接着被 nextLine() 读走了。

解决方案:

// 方案一:额外调用一次 nextLine() 吸收残留换行符
System.out.print("请输入年龄: ");
int age = sc.nextInt();
sc.nextLine(); // 吸收掉换行符

System.out.print("请输入姓名: ");
String name = sc.nextLine(); // 正常等待用户输入

// 方案二:统一用 nextLine() 读取,再手动类型转换
System.out.print("请输入年龄: ");
int age = Integer.parseInt(sc.nextLine());

System.out.print("请输入姓名: ");
String name = sc.nextLine(); // 不会有问题

1.4 综合示例

import java.util.Scanner;

public class ScannerDemo {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        System.out.print("请输入整数: ");
        int i = sc.nextInt();

        System.out.print("请输入浮点数: ");
        double d = sc.nextDouble();

        sc.nextLine(); // 吸收残留的换行符

        System.out.print("请输入一句话: ");
        String s = sc.nextLine();

        System.out.println("汇总: " + i + " / " + d + " / " + s);

        sc.close();
    }
}

1.5 hasNext 系列——安全的输入判断

Scanner sc = new Scanner(System.in);

System.out.print("请输入一个整数: ");
if (sc.hasNextInt()) {
    int num = sc.nextInt();
    System.out.println("你输入的是: " + num);
} else {
    System.out.println("输入不是整数!");
}

sc.close();

二、顺序结构

Java 默认按代码书写顺序从上到下逐行执行,是最基本的程序结构。

System.out.println("第一步");
System.out.println("第二步");
System.out.println("第三步");
// 输出顺序: 第一步 → 第二步 → 第三步

三、选择结构(if-else / switch)

3.1 if 单分支

if (score >= 60) {
    System.out.println("及格");
}

3.2 if-else 双分支

if (score >= 60) {
    System.out.println("及格");
} else {
    System.out.println("不及格");
}

3.3 if-else if 多分支

if (score >= 90) {
    System.out.println("优秀");
} else if (score >= 80) {
    System.out.println("良好");
} else if (score >= 60) {
    System.out.println("及格");
} else {
    System.out.println("不及格");
}

3.4 switch 语句

int day = 3;
switch (day) {
    case 1:
        System.out.println("星期一");
        break; // 必须有 break,否则会穿透到下个 case
    case 2:
        System.out.println("星期二");
        break;
    case 3:
        System.out.println("星期三");
        break;
    // ... case 4 ~ 7
    default:
        System.out.println("无效的星期");
}

switch 支持的类型: byteshortintchar 及其包装类、String(JDK 7+)、enum 枚举(JDK 5+)。

3.5 JDK 14+ switch 表达式(新写法)

// 使用 -> 箭头语法,自带 break,更简洁
String result = switch (day) {
    case 1 -> "星期一";
    case 2 -> "星期二";
    case 3 -> "星期三";
    default -> "无效";
};
System.out.println(result);

3.6 case 穿透(fall-through)的巧用

// 多个 case 共享同一处理逻辑
int month = 3;
switch (month) {
    case 3:
    case 4:
    case 5:
        System.out.println("春季");
        break;
    case 6:
    case 7:
    case 8:
        System.out.println("夏季");
        break;
    case 9:
    case 10:
    case 11:
        System.out.println("秋季");
        break;
    case 12:
    case 1:
    case 2:
        System.out.println("冬季");
        break;
}

四、循环结构

4.1 for 循环

// 语法: for(初始化; 条件; 迭代) { 循环体; }
for (int i = 0; i < 5; i++) {
    System.out.println("i = " + i);
}
// 输出: 0 1 2 3 4

执行顺序: 初始化 → 判断条件(true) → 执行循环体 → 迭代 → 判断条件(true) → ... → 判断条件(false) → 退出

4.2 增强 for 循环(for-each)

// 遍历数组
int[] arr = {10, 20, 30, 40, 50};
for (int num : arr) {
    System.out.println(num);
}

// 遍历集合
List<String> names = Arrays.asList("张三", "李四", "王五");
for (String name : names) {
    System.out.println(name);
}

增强 for 循环适合只读遍历,无法获取索引,也不能修改集合结构。

4.3 while 循环

// 先判断后执行,可能一次都不执行
int i = 0;
while (i < 5) {
    System.out.println("i = " + i);
    i++;
}

4.4 do-while 循环

// 先执行后判断,至少执行一次
int i = 0;
do {
    System.out.println("i = " + i);
    i++;
} while (i < 5);

典型应用场景: 至少需要用户输入一次,然后根据输入决定是否继续。

Scanner sc = new Scanner(System.in);
String answer;
do {
    System.out.println("好好学习了吗? (y/n)");
    answer = sc.next();
} while (!"y".equals(answer));
System.out.println("很好!");
sc.close();

4.5 三种循环对比

特性 for while do-while
最少执行次数 0 次 0 次 1 次
适用场景 明确循环次数 次数不固定,条件驱动 至少执行一次
循环变量作用域 仅在 for 内有效 在外部定义,循环外也可用 在外部定义,循环外也可用

4.6 嵌套循环

// 九九乘法表
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();
}

五、break 和 continue

5.1 break — 终止整个循环

for (int i = 0; i < 10; i++) {
    if (i == 5) {
        break; // 直接退出循环
    }
    System.out.print(i + " ");
}
// 输出: 0 1 2 3 4

5.2 continue — 跳过本次迭代

for (int i = 0; i < 10; i++) {
    if (i % 2 == 0) {
        continue; // 跳过本次循环的剩余代码,进入下一次迭代
    }
    System.out.print(i + " ");
}
// 输出: 1 3 5 7 9

5.3 带标签的 break / continue

标签用于精准控制在嵌套循环中跳出哪一层。

// 带标签的 break: 跳出指定层级的循环
outer:
for (int i = 1; i <= 3; i++) {
    for (int j = 1; j <= 3; j++) {
        if (i * j > 4) {
            break outer; // 跳出标记为 outer 的外层循环
        }
        System.out.println("i=" + i + ", j=" + j);
    }
}
// 输出: i=1,j=1  i=1,j=2  i=1,j=3  i=2,j=1  i=2,j=2
// i=2,j=3 时 i*j=6>4,跳出整个外层循环

System.out.println("---");

// 带标签的 continue: 跳到指定层级的下一次迭代
outer2:
for (int i = 1; i <= 3; i++) {
    for (int j = 1; j <= 3; j++) {
        if (j == 2) {
            continue outer2; // 跳到外层循环的下一次 i++
        }
        System.out.println("i=" + i + ", j=" + j);
    }
}
// 输出: (1,1) (2,1) (3,1)
// 每次内层 j==2 时跳过并进入外层 i++,所以只有 j=1 的行被打印

5.4 死循环

// 三种等价的死循环写法
for (;;) {
    // 循环体
}

while (true) {
    // 循环体
}

// 配合 break 退出
while (true) {
    System.out.print("输入 'exit' 退出: ");
    String input = new Scanner(System.in).next();
    if ("exit".equals(input)) {
        break;
    }
}

补充参考

说明 链接
本章原文 CSDN - Shane_Cheng0202
基础语法笔记 note_java.md
posted @ 2026-06-24 15:26  哇扣  阅读(5)  评论(0)    收藏  举报