2. java循环控制
Java Scanner 类 & 循环控制语句笔记
一、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 支持的类型: byte、short、int、char 及其包装类、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 |

浙公网安备 33010602011771号