Java选择语句和循环语句
Java 基础笔记:选择语句与循环语句
本章位置:Java 核心基础
学习目标:掌握程序流程控制,能够使用if、switch完成条件判断,使用for、while、do-while完成重复执行,并理解break、continue的作用。
一、什么是流程控制
Java 程序默认按照代码从上到下依次执行。
例如:
public class Demo {
public static void main(String[] args) {
System.out.println("第一句");
System.out.println("第二句");
System.out.println("第三句");
}
}
运行结果:
第一句
第二句
第三句
这种执行方式称为:
顺序结构
但实际程序不可能永远只按照固定顺序执行。
例如:
如果登录成功,进入首页
如果登录失败,提示账号或密码错误
如果考试成绩 >= 60,显示及格
否则显示不及格
一段代码重复执行 10 次
遍历 1 ~ 100
因此程序中还需要:
选择结构
循环结构
Java 基础中的三种流程结构可以概括为:
流程控制
│
├─ 顺序结构
│
├─ 选择结构
│ ├─ if
│ └─ switch
│
└─ 循环结构
├─ for
├─ while
└─ do-while
二、选择语句
选择语句用于根据不同条件执行不同代码。
最常见的两种:
if
switch
三、if 单分支语句
最基本的 if 语法:
if (条件) {
条件成立时执行的代码;
}
其中条件的最终结果必须是:
boolean
也就是:
true
false
示例:判断是否成年
public class IfDemo {
public static void main(String[] args) {
int age = 20;
if (age >= 18) {
System.out.println("已经成年");
}
}
}
执行过程:
age = 20
age >= 18
↓
true
↓
执行 if 中的代码
输出:
已经成年
条件不成立时
int age = 16;
if (age >= 18) {
System.out.println("已经成年");
}
此时:
age >= 18
↓
false
所以:
System.out.println("已经成年");
不会执行。
四、if 条件必须是 boolean
Java 中:
if (...)
括号中的结果必须是布尔值。
正确:
int age = 18;
if (age >= 18) {
System.out.println("成年");
}
因为:
age >= 18
最终结果是:
true 或 false
错误:
int age = 18;
if (age) {
System.out.println("成年");
}
Java 不允许直接把整数当作真假条件。
五、if-else 双分支语句
当条件只有两种结果时,可以使用:
if ... else
语法:
if (条件) {
条件成立执行;
} else {
条件不成立执行;
}
示例:判断是否及格
public class ScoreDemo {
public static void main(String[] args) {
int score = 75;
if (score >= 60) {
System.out.println("考试及格");
} else {
System.out.println("考试不及格");
}
}
}
输出:
考试及格
如果:
int score = 50;
输出:
考试不及格
六、if-else if-else 多分支语句
如果有多个判断区间,可以使用:
if
else if
else
语法:
if (条件1) {
} else if (条件2) {
} else if (条件3) {
} else {
}
示例:成绩等级
需求:
90 ~ 100 优秀
80 ~ 89 良好
60 ~ 79 及格
0 ~ 59 不及格
代码:
public class ScoreLevelDemo {
public static void main(String[] args) {
int score = 85;
if (score >= 90) {
System.out.println("优秀");
} else if (score >= 80) {
System.out.println("良好");
} else if (score >= 60) {
System.out.println("及格");
} else {
System.out.println("不及格");
}
}
}
输出:
良好
七、else if 的执行顺序
这一点非常重要。
if (条件1) {
} else if (条件2) {
} else if (条件3) {
} else {
}
Java 会从上往下依次判断。
只要某一个条件成立:
后面的条件就不会继续判断
例如:
int score = 95;
if (score >= 60) {
System.out.println("及格");
} else if (score >= 80) {
System.out.println("良好");
} else if (score >= 90) {
System.out.println("优秀");
}
输出:
及格
为什么?
因为第一个条件:
score >= 60
对于 95 来说已经成立。
后面的:
score >= 80
score >= 90
不会再执行。
因此多个范围判断时,一定要考虑顺序。
更合理的写法:
if (score >= 90) {
System.out.println("优秀");
} else if (score >= 80) {
System.out.println("良好");
} else if (score >= 60) {
System.out.println("及格");
} else {
System.out.println("不及格");
}
八、判断数据是否合法
实际开发中,不仅要判断业务结果,还要注意输入数据是否合法。
例如考试成绩理论范围:
0 ~ 100
可以写:
int score = 120;
if (score < 0 || score > 100) {
System.out.println("成绩输入有误");
} else if (score >= 90) {
System.out.println("优秀");
} else if (score >= 80) {
System.out.println("良好");
} else if (score >= 60) {
System.out.println("及格");
} else {
System.out.println("不及格");
}
这种写法比直接判断成绩等级更完整。
九、if 语句中的大括号
如果 if 中只有一条语句,Java 语法允许省略 {}。
例如:
if (age >= 18)
System.out.println("成年");
虽然能运行,但不推荐。
推荐始终写:
if (age >= 18) {
System.out.println("成年");
}
原因是以后增加代码时更安全。
例如:
if (age >= 18)
System.out.println("成年");
System.out.println("可以注册");
很多初学者以为两句都属于 if。
实际上只有:
System.out.println("成年");
属于 if。
而:
System.out.println("可以注册");
无论条件是否成立都会执行。
因此开发中建议:
即使只有一行代码,也保留
{}。
十、if 嵌套
if 中还可以继续写 if。
例如:
int age = 20;
boolean hasTicket = true;
if (age >= 18) {
if (hasTicket) {
System.out.println("允许进入");
}
}
这种结构叫:
嵌套 if
示例:登录判断
String username = "admin";
String password = "123456";
if ("admin".equals(username)) {
if ("123456".equals(password)) {
System.out.println("登录成功");
} else {
System.out.println("密码错误");
}
} else {
System.out.println("账号不存在");
}
这里暂时只需要理解结构。
关于字符串比较,后面学习 String 时会详细讲。
十一、if 条件的常见组合
条件判断经常配合关系运算符和逻辑运算符。
例如:
int age = 25;
if (age >= 18 && age <= 60) {
System.out.println("年龄符合要求");
}
这里使用:
>=
<=
&&
再例如:
int score = 50;
if (score < 0 || score > 100) {
System.out.println("成绩输入错误");
}
这里使用:
<
>
||
因此:
关系运算符 + 逻辑运算符
几乎就是 if 的基础搭档。
十二、判断奇偶数
利用:
%
可以判断奇偶数。
int number = 10;
if (number % 2 == 0) {
System.out.println("偶数");
} else {
System.out.println("奇数");
}
判断原理:
一个整数除以 2
余数为 0 → 偶数
余数不为 0 → 奇数
十三、判断闰年
闰年的基本规则:
能够被 4 整除但不能被 100 整除
或者
能够被 400 整除
代码:
int year = 2024;
if ((year % 4 == 0 && year % 100 != 0)
|| year % 400 == 0) {
System.out.println(year + " 是闰年");
} else {
System.out.println(year + " 不是闰年");
}
这里综合使用:
%
==
!=
&&
||
十四、switch 选择语句
当一个变量需要和多个固定值进行匹配时,可以考虑:
switch
经典语法:
switch (表达式) {
case 值1:
代码;
break;
case 值2:
代码;
break;
default:
代码;
break;
}
十五、switch 基本示例
public class SwitchDemo {
public static void main(String[] args) {
int week = 1;
switch (week) {
case 1:
System.out.println("星期一");
break;
case 2:
System.out.println("星期二");
break;
case 3:
System.out.println("星期三");
break;
case 4:
System.out.println("星期四");
break;
case 5:
System.out.println("星期五");
break;
case 6:
System.out.println("星期六");
break;
case 7:
System.out.println("星期日");
break;
default:
System.out.println("输入有误");
break;
}
}
}
如果:
week = 1;
输出:
星期一
十六、switch 的执行过程
例如:
int week = 3;
Java 会拿:
week
依次和:
case 1
case 2
case 3
...
匹配。
当找到:
case 3:
就开始执行对应代码。
遇到:
break;
结束整个 switch。
十七、break 在 switch 中的作用
break 表示:
结束当前 switch
例如:
case 1:
System.out.println("星期一");
break;
如果没有 break:
case 1:
System.out.println("星期一");
case 2:
System.out.println("星期二");
case 3:
System.out.println("星期三");
当:
week = 1;
可能输出:
星期一
星期二
星期三
这种现象叫:
case 穿透
十八、switch 穿透
示例:
int number = 1;
switch (number) {
case 1:
System.out.println("A");
case 2:
System.out.println("B");
case 3:
System.out.println("C");
}
输出:
A
B
C
原因:
匹配 case 1 后开始执行
由于没有 break
程序继续向下执行其他 case 中的代码
所以经典 switch 中通常要记得写:
break;
十九、合理利用 switch 穿透
穿透不一定永远是错误。
例如:
int month = 2;
switch (month) {
case 12:
case 1:
case 2:
System.out.println("冬季");
break;
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;
default:
System.out.println("月份错误");
break;
}
这里:
12、1、2
都会执行:
System.out.println("冬季");
这种写法就是有意识地利用穿透。
二十、default
default 类似于 if 中的:
else
当所有 case 都不匹配时执行。
例如:
int week = 10;
switch (week) {
case 1:
System.out.println("星期一");
break;
case 2:
System.out.println("星期二");
break;
default:
System.out.println("输入错误");
break;
}
输出:
输入错误
二十一、switch 可以使用哪些类型
常见情况下 switch 可以处理:
byte
short
char
int
String
enum
例如可以判断字符串:
String role = "admin";
switch (role) {
case "admin":
System.out.println("管理员");
break;
case "student":
System.out.println("学生");
break;
default:
System.out.println("未知角色");
break;
}
不能直接使用:
float
double
boolean
作为传统 switch 的匹配表达式。
二十二、if 和 switch 怎么选择
if 更适合:
范围判断
复杂条件判断
多个逻辑条件组合
例如:
if (score >= 90) {
}
if (age >= 18 && age <= 60) {
}
switch 更适合:
一个变量
和多个固定值进行匹配
例如:
星期
月份
菜单编号
角色类型
状态码
可以简单理解:
判断范围 → if
匹配固定值 → switch
二十三、JDK 17 中的 switch 新写法
如果使用的是较新的 Java,例如 JDK 17,可以使用更简洁的 switch 写法。
例如:
int week = 1;
switch (week) {
case 1 -> System.out.println("星期一");
case 2 -> System.out.println("星期二");
case 3 -> System.out.println("星期三");
default -> System.out.println("输入错误");
}
这种写法的一个好处是:
不需要写 break
也不会产生传统的 case 穿透问题。
多个 case 写在一起
int month = 2;
switch (month) {
case 12, 1, 2 ->
System.out.println("冬季");
case 3, 4, 5 ->
System.out.println("春季");
case 6, 7, 8 ->
System.out.println("夏季");
case 9, 10, 11 ->
System.out.println("秋季");
default ->
System.out.println("月份错误");
}
二十四、switch 表达式
JDK 17 中还可以让 switch 直接产生一个结果。
例如:
int week = 1;
String result = switch (week) {
case 1 -> "星期一";
case 2 -> "星期二";
case 3 -> "星期三";
case 4 -> "星期四";
case 5 -> "星期五";
case 6 -> "星期六";
case 7 -> "星期日";
default -> "输入错误";
};
System.out.println(result);
这种写法叫:
switch 表达式
初学阶段先掌握传统 switch,再熟悉这种现代写法即可。
二十五、循环结构
循环用于:
让一段代码重复执行
例如:
打印 10 次 Hello
输出 1 ~ 100
计算 1 ~ 100 的和
遍历数组
遍历集合
读取数据
批量处理任务
Java 中常见循环:
for
while
do-while
二十六、为什么需要循环
如果要打印 5 次:
Hello Java
不用循环:
System.out.println("Hello Java");
System.out.println("Hello Java");
System.out.println("Hello Java");
System.out.println("Hello Java");
System.out.println("Hello Java");
如果打印:
1000 次
显然不能这样写。
使用循环:
for (int i = 0; i < 1000; i++) {
System.out.println("Hello Java");
}
这就是循环存在的意义。
二十七、for 循环
基本语法:
for (初始化语句; 条件判断; 条件控制) {
循环体;
}
最常见写法:
for (int i = 0; i < 5; i++) {
System.out.println("Hello Java");
}
二十八、for 循环的执行顺序
看代码:
for (int i = 0; i < 3; i++) {
System.out.println(i);
}
执行过程:
① int i = 0
② 判断 i < 3
③ 条件成立,执行循环体
④ 执行 i++
⑤ 再判断 i < 3
⑥ 条件成立,继续执行
...
直到条件为 false
可以画成:
初始化
↓
判断条件 ←────────┐
↓ true │
执行循环体 │
↓ │
条件控制 ----------┘
↓ false
结束循环
二十九、for 循环输出 1 到 10
for (int i = 1; i <= 10; i++) {
System.out.println(i);
}
输出:
1
2
3
4
5
6
7
8
9
10
三十、for 循环输出 10 到 1
for (int i = 10; i >= 1; i--) {
System.out.println(i);
}
输出:
10
9
8
7
6
5
4
3
2
1
这里使用:
i--
每次减 1。
三十一、循环变量 i
循环中经常使用:
i
作为计数变量。
例如:
for (int i = 0; i < 10; i++) {
}
其中:
i = index
通常表示索引或计数。
嵌套循环中还常见:
i
j
k
三十二、for 循环计算 1 ~ 100 的和
需求:
1 + 2 + 3 + ... + 100
代码:
public class SumDemo {
public static void main(String[] args) {
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
}
System.out.println(sum);
}
}
输出:
5050
执行过程
初始:
sum = 0
第一次:
i = 1
sum = sum + 1
sum = 1
第二次:
i = 2
sum = sum + 2
sum = 3
第三次:
i = 3
sum = sum + 3
sum = 6
一直执行到:
i = 100
最终:
sum = 5050
这种变量:
int sum = 0;
常被称为:
累加变量
三十三、计算 1 ~ 100 的偶数和
int sum = 0;
for (int i = 1; i <= 100; i++) {
if (i % 2 == 0) {
sum += i;
}
}
System.out.println(sum);
这里综合使用了:
for
if
%
==
+=
更直接的写法
int sum = 0;
for (int i = 2; i <= 100; i += 2) {
sum += i;
}
System.out.println(sum);
因为偶数是:
2
4
6
8
...
所以每次:
i += 2;
即可。
三十四、while 循环
基本语法:
while (条件) {
循环体;
}
只要条件为:
true
循环就继续执行。
示例
int i = 1;
while (i <= 5) {
System.out.println(i);
i++;
}
输出:
1
2
3
4
5
三十五、while 的执行过程
代码:
int i = 1;
while (i <= 3) {
System.out.println(i);
i++;
}
执行:
i = 1
判断 i <= 3
↓
true
输出 1
i++
i = 2
判断 i <= 3
↓
true
输出 2
i++
i = 3
判断 i <= 3
↓
true
输出 3
i++
i = 4
判断 i <= 3
↓
false
循环结束
三十六、for 和 while 的关系
下面两个循环基本等价。
for
for (int i = 1; i <= 5; i++) {
System.out.println(i);
}
while
int i = 1;
while (i <= 5) {
System.out.println(i);
i++;
}
所以很多时候:
for 和 while 可以互相转换
三十七、for 和 while 怎么选
如果循环次数比较明确:
循环 10 次
遍历 1 ~ 100
遍历数组
通常优先使用:
for
例如:
for (int i = 0; i < 10; i++) {
}
如果循环次数不确定,只知道结束条件:
一直输入,直到输入正确
一直运行,直到用户退出
余额不足之前一直扣款
通常更适合:
while
例如:
while (条件) {
}
可以简单记:
次数明确 → for
次数不明确,只知道条件 → while
三十八、do-while 循环
语法:
do {
循环体;
} while (条件);
注意最后有:
;
完整示例:
int i = 1;
do {
System.out.println(i);
i++;
} while (i <= 5);
输出:
1
2
3
4
5
三十九、do-while 的特点
while:
先判断
再执行
do-while:
先执行
再判断
所以:
do-while至少会执行一次循环体。
对比
while
int i = 10;
while (i < 5) {
System.out.println("执行");
}
因为:
10 < 5
一开始就是:
false
所以一次都不会执行。
do-while
int i = 10;
do {
System.out.println("执行");
} while (i < 5);
虽然条件是:
false
但还是会先执行一次。
输出:
执行
四十、三种循环总结
| 循环 | 特点 | 常见用途 |
|---|---|---|
for |
循环次数通常明确 | 计数、遍历 |
while |
先判断再执行 | 次数不确定 |
do-while |
至少执行一次 | 菜单、输入确认 |
初学阶段使用频率通常是:
for > while > do-while
四十一、死循环
如果循环条件永远为:
true
循环就不会结束。
这种情况叫:
死循环
例如:
while (true) {
System.out.println("一直执行");
}
for 死循环
for (;;) {
System.out.println("一直执行");
}
这种写法也是合法的。
死循环一定是错误吗
不一定。
例如:
服务器程序
监听程序
消息消费
游戏主循环
菜单程序
可能本身就需要长时间运行。
通常会结合:
break
在满足条件时退出。
四十二、break
break 的作用:
立即结束当前循环
例如:
for (int i = 1; i <= 10; i++) {
if (i == 5) {
break;
}
System.out.println(i);
}
输出:
1
2
3
4
当:
i == 5
执行:
break;
整个循环直接结束。
所以:
5
6
7
8
9
10
都不会再执行。
四十三、continue
continue 的作用:
跳过本次循环
继续下一次循环
例如:
for (int i = 1; i <= 5; i++) {
if (i == 3) {
continue;
}
System.out.println(i);
}
输出:
1
2
4
5
当:
i == 3
执行:
continue;
所以本次循环后面的:
System.out.println(i);
被跳过。
然后继续:
i = 4
四十四、break 和 continue 的区别
这是很常见的考点。
break
结束整个循环
continue
只结束本次循环
继续下一次
例如循环:
1 2 3 4 5
遇到 3。
使用:
break;
可能得到:
1 2
使用:
continue;
可能得到:
1 2 4 5
可以记:
break 整个循环不干了
continue 这一次不干了,下一次继续
四十五、break 配合死循环
例如:
int i = 1;
while (true) {
System.out.println(i);
if (i == 5) {
break;
}
i++;
}
输出:
1
2
3
4
5
虽然:
while (true)
本身是死循环,
但:
break;
可以在满足条件时结束循环。
四十六、continue 的一个常见问题
看下面代码:
int i = 1;
while (i <= 5) {
if (i == 3) {
continue;
}
System.out.println(i);
i++;
}
这段代码会出现问题。
当:
i = 3
进入:
continue;
后:
i++;
没有机会执行。
于是:
i 永远等于 3
循环就一直执行。
形成:
死循环
正确写法可以是:
int i = 1;
while (i <= 5) {
if (i == 3) {
i++;
continue;
}
System.out.println(i);
i++;
}
因此在 while 中使用 continue 时,要特别注意循环变量是否还能正常变化。
四十七、循环嵌套
循环内部还可以继续写循环。
例如:
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 2; j++) {
System.out.println(
"i = " + i + ", j = " + j
);
}
}
输出:
i = 1, j = 1
i = 1, j = 2
i = 2, j = 1
i = 2, j = 2
i = 3, j = 1
i = 3, j = 2
四十八、理解外层循环和内层循环
代码:
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 2; j++) {
}
}
可以理解为:
外层循环执行 1 次
内层循环完整执行 2 次
外层一共执行:
3 次
因此内层总执行次数:
3 × 2 = 6 次
四十九、打印矩形
需求:
*****
*****
*****
代码:
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 5; j++) {
System.out.print("*");
}
System.out.println();
}
注意:
System.out.print("*");
不会自动换行。
而:
System.out.println();
用于换行。
五十、打印三角形
输出:
*
**
***
****
*****
代码:
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= i; j++) {
System.out.print("*");
}
System.out.println();
}
为什么是 j <= i
当:
i = 1
内层执行:
1 次
打印:
*
当:
i = 2
内层执行:
2 次
打印:
**
当:
i = 5
内层执行:
5 次
打印:
*****
所以每一行打印多少个 *,由:
i
决定。
五十一、九九乘法表
九九乘法表是嵌套循环的经典练习。
public class MultiplicationTable {
public static void main(String[] args) {
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();
}
}
}
部分输出:
1×1=1
1×2=2 2×2=4
1×3=3 2×3=6 3×3=9
...
五十二、嵌套循环中的 break
例如:
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 5; j++) {
if (j == 3) {
break;
}
System.out.println(
"i = " + i + ", j = " + j
);
}
}
这里的:
break;
只结束:
当前所在的内层循环
不会直接结束外层循环。
因此:
外层循环仍然继续
五十三、标签 break
Java 支持给循环加标签。
例如:
outer:
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 5; j++) {
if (j == 3) {
break outer;
}
System.out.println(
"i = " + i + ", j = " + j
);
}
}
这里:
break outer;
可以直接结束被 outer 标记的外层循环。
不过实际开发中:
标签跳转不要滥用,否则代码会比较难读。
初学阶段知道它存在即可。
五十四、Scanner 接收用户输入
为了让练习更接近真实程序,可以使用:
Scanner
接收键盘输入。
首先导入:
import java.util.Scanner;
创建对象:
Scanner scanner = new Scanner(System.in);
读取整数:
int number = scanner.nextInt();
完整示例:
import java.util.Scanner;
public class InputDemo {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入一个整数:");
int number = scanner.nextInt();
System.out.println("你输入的是:" + number);
scanner.close();
}
}
五十五、练习:用户输入成绩并判断等级
import java.util.Scanner;
public class ScoreDemo {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入成绩:");
int score = scanner.nextInt();
if (score < 0 || score > 100) {
System.out.println("成绩输入错误");
} else if (score >= 90) {
System.out.println("优秀");
} else if (score >= 80) {
System.out.println("良好");
} else if (score >= 60) {
System.out.println("及格");
} else {
System.out.println("不及格");
}
scanner.close();
}
}
五十六、练习:简单菜单
需求:
1. 查询用户
2. 添加用户
3. 删除用户
4. 退出系统
代码:
import java.util.Scanner;
public class MenuDemo {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("1. 查询用户");
System.out.println("2. 添加用户");
System.out.println("3. 删除用户");
System.out.println("4. 退出系统");
System.out.print("请选择:");
int choice = scanner.nextInt();
switch (choice) {
case 1:
System.out.println("正在查询用户");
break;
case 2:
System.out.println("正在添加用户");
break;
case 3:
System.out.println("正在删除用户");
break;
case 4:
System.out.println("退出系统");
break;
default:
System.out.println("选项不存在");
break;
}
scanner.close();
}
}
五十七、练习:循环菜单
如果希望菜单可以重复使用,可以结合:
while
switch
break
例如:
import java.util.Scanner;
public class MenuLoopDemo {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
boolean running = true;
while (running) {
System.out.println();
System.out.println("===== 用户管理系统 =====");
System.out.println("1. 查询用户");
System.out.println("2. 添加用户");
System.out.println("3. 删除用户");
System.out.println("4. 退出系统");
System.out.print("请选择:");
int choice = scanner.nextInt();
switch (choice) {
case 1:
System.out.println("正在查询用户");
break;
case 2:
System.out.println("正在添加用户");
break;
case 3:
System.out.println("正在删除用户");
break;
case 4:
System.out.println("系统已退出");
running = false;
break;
default:
System.out.println("请输入正确的选项");
break;
}
}
scanner.close();
}
}
这段代码已经很接近后面做控制台管理系统时的基本结构。
五十八、练习:猜数字的基本结构
先固定一个答案:
int answer = 66;
让用户不断输入数字。
如果猜对:
退出循环
代码:
import java.util.Scanner;
public class GuessNumberDemo {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int answer = 66;
while (true) {
System.out.print("请输入你猜的数字:");
int number = scanner.nextInt();
if (number > answer) {
System.out.println("猜大了");
} else if (number < answer) {
System.out.println("猜小了");
} else {
System.out.println("猜对了");
break;
}
}
scanner.close();
}
}
这里综合使用:
while
if
else if
else
break
Scanner
五十九、练习:统计 1 ~ 100 中能被 3 整除的数字
int count = 0;
for (int i = 1; i <= 100; i++) {
if (i % 3 == 0) {
System.out.println(i);
count++;
}
}
System.out.println(
"一共有 " + count + " 个数字"
);
这里的:
count++;
表示每找到一个符合条件的数字:
计数器 + 1
这也是循环中很常见的:
计数思想
六十、累加和计数的区别
循环题中经常出现两类变量。
累加
例如求总分:
int sum = 0;
sum += score;
核心:
把数据不断加到 sum 中
计数
例如统计及格人数:
int count = 0;
count++;
核心:
每出现一次符合条件的情况
count 加 1
可以记:
求总数、总和 → 累加
求有几个 → 计数
六十一、练习:求 1 ~ 100 中所有奇数的和
int sum = 0;
for (int i = 1; i <= 100; i++) {
if (i % 2 != 0) {
sum += i;
}
}
System.out.println(
"奇数和:" + sum
);
六十二、练习:求阶乘
例如:
5! = 5 × 4 × 3 × 2 × 1
代码:
int result = 1;
for (int i = 1; i <= 5; i++) {
result *= i;
}
System.out.println(result);
输出:
120
为什么:
result = 1
而不是:
result = 0
因为乘法中:
任何数 × 0 = 0
如果从 0 开始,结果永远都是 0。
六十三、练习:求最大公约数的基础写法
例如:
12 和 18
公约数有:
1
2
3
6
最大公约数:
6
基础循环写法:
int a = 12;
int b = 18;
int max = 1;
for (int i = 1; i <= a && i <= b; i++) {
if (a % i == 0 && b % i == 0) {
max = i;
}
}
System.out.println(
"最大公约数:" + max
);
后面学习算法后,还可以使用更高效的:
欧几里得算法
当前阶段先练习循环和条件即可。
六十四、练习:判断一个数是不是质数
质数:
只能被 1 和自身整除的正整数
例如:
2
3
5
7
11
13
基础写法:
int number = 17;
boolean prime = true;
if (number < 2) {
prime = false;
} else {
for (int i = 2; i < number; i++) {
if (number % i == 0) {
prime = false;
break;
}
}
}
if (prime) {
System.out.println(number + " 是质数");
} else {
System.out.println(number + " 不是质数");
}
更好的判断范围
实际上不需要判断到:
number - 1
可以先写成:
for (int i = 2; i * i <= number; i++) {
if (number % i == 0) {
prime = false;
break;
}
}
这一版效率更高。
初学阶段重点不是记算法,而是理解:
循环遍历可能的除数
如果能够整除
说明不是质数
然后 break 提前结束循环
六十五、练习:打印 1 ~ 100 中的所有质数
for (int number = 2; number <= 100; number++) {
boolean prime = true;
for (int i = 2; i * i <= number; i++) {
if (number % i == 0) {
prime = false;
break;
}
}
if (prime) {
System.out.println(number);
}
}
这里包含:
外层循环:遍历 2 ~ 100
内层循环:判断当前 number 是否为质数
六十六、循环中的变量作用域
例如:
for (int i = 0; i < 5; i++) {
System.out.println(i);
}
这里的:
i
是在 for 中定义的。
循环结束后:
System.out.println(i);
不能直接使用。
因为:
i 的作用域只在 for 循环范围内
如果循环结束后还要使用
可以提前定义:
int i;
for (i = 0; i < 5; i++) {
System.out.println(i);
}
System.out.println(i);
六十七、循环条件中的边界问题
最常见的是:
<
和:
<=
混淆。
例如:
for (int i = 1; i < 10; i++) {
}
实际范围:
1 ~ 9
而:
for (int i = 1; i <= 10; i++) {
}
实际范围:
1 ~ 10
写循环时一定要先想清楚:
起始值
结束值
是否包含结束值
每次变化多少
六十八、常见循环错误:条件写反
错误:
for (int i = 1; i >= 10; i++) {
System.out.println(i);
}
一开始:
i = 1
判断:
1 >= 10
结果:
false
所以循环一次都不会执行。
正确:
for (int i = 1; i <= 10; i++) {
System.out.println(i);
}
六十九、常见循环错误:忘记改变变量
例如:
int i = 1;
while (i <= 10) {
System.out.println(i);
}
因为:
i 一直等于 1
所以:
i <= 10
永远成立。
最终形成死循环。
正确:
int i = 1;
while (i <= 10) {
System.out.println(i);
i++;
}
七十、常见循环错误:多写分号
错误:
for (int i = 1; i <= 5; i++); {
System.out.println("Hello");
}
注意:
for (...);
后面多了一个:
;
这个分号实际上代表一个空循环体。
后面的:
{
System.out.println("Hello");
}
已经不属于 for。
因此写循环时要注意:
for (...) {
}
而不是:
for (...); {
}
七十一、常见错误:循环边界多一次或少一次
例如想循环:
5 次
写成:
for (int i = 0; i <= 5; i++) {
}
实际执行:
6 次
因为:
i = 0
1
2
3
4
5
一共有 6 个值。
如果从 0 开始循环 5 次:
for (int i = 0; i < 5; i++) {
}
范围:
0
1
2
3
4
正好 5 次。
这种问题以后学习数组时会非常重要。
七十二、0 开始还是 1 开始
两种写法都可以。
从 1 开始
for (int i = 1; i <= 10; i++) {
}
适合:
第 1 次
第 2 次
...
第 10 次
从 0 开始
for (int i = 0; i < 10; i++) {
}
适合:
数组索引
集合索引
程序中的下标
后面学习数组时会大量看到:
for (int i = 0; i < array.length; i++) {
}
七十三、循环中的提前退出思想
有时不需要把整个循环执行完。
例如:
在 100 个数据中查找一个目标值
找到之后:
就没有必要继续找
可以使用:
break;
例如:
for (int i = 1; i <= 100; i++) {
if (i == 37) {
System.out.println("找到了");
break;
}
}
这种思想以后会经常出现在:
数组查找
集合查找
数据库结果处理
算法
中。
七十四、continue 的实际用途
例如输出 1 ~ 20 中所有不是 3 的倍数的数字:
for (int i = 1; i <= 20; i++) {
if (i % 3 == 0) {
continue;
}
System.out.println(i);
}
这里:
3
6
9
12
15
18
都会被跳过。
七十五、条件判断的简化
有时候初学者会写:
boolean login = true;
if (login == true) {
System.out.println("已经登录");
}
虽然没错,但更常见的写法是:
if (login) {
System.out.println("已经登录");
}
如果判断:
没有登录
可以写:
if (!login) {
System.out.println("请先登录");
}
比:
if (login == false)
更简洁。
七十六、避免过度嵌套
例如:
if (条件1) {
if (条件2) {
if (条件3) {
if (条件4) {
}
}
}
}
虽然语法没有问题,但嵌套过深会让代码很难读。
随着后面学习方法和面向对象,可以逐渐通过:
提前 return
拆分方法
封装业务逻辑
减少嵌套。
当前阶段先建立一个习惯:
条件结构能简单就不要故意写得很复杂。
七十七、三元运算符和 if 的选择
例如:
int age = 20;
三元运算符:
String result = age >= 18
? "成年"
: "未成年";
使用 if:
String result;
if (age >= 18) {
result = "成年";
} else {
result = "未成年";
}
如果只是:
根据一个条件得到两个结果中的一个
三元运算符比较简洁。
如果需要执行多条业务代码:
优先使用 if
七十八、switch 和 if 的转换
下面的 switch:
int week = 1;
switch (week) {
case 1:
System.out.println("星期一");
break;
case 2:
System.out.println("星期二");
break;
default:
System.out.println("错误");
}
也可以写成:
if (week == 1) {
System.out.println("星期一");
} else if (week == 2) {
System.out.println("星期二");
} else {
System.out.println("错误");
}
两种方式都可以。
选择哪种主要看:
哪一种更清晰
七十九、综合案例:学生成绩统计
需求:
用户输入 5 名学生的成绩,统计:
总分
平均分
最高分
及格人数
不及格人数
代码:
import java.util.Scanner;
public class ScoreStatistics {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int sum = 0;
int max = 0;
int passCount = 0;
int failCount = 0;
for (int i = 1; i <= 5; i++) {
System.out.print(
"请输入第 " + i + " 名学生的成绩:"
);
int score = scanner.nextInt();
if (score < 0 || score > 100) {
System.out.println("成绩输入错误,请重新输入");
i--;
continue;
}
sum += score;
if (score > max) {
max = score;
}
if (score >= 60) {
passCount++;
} else {
failCount++;
}
}
double average = sum / 5.0;
System.out.println();
System.out.println("总分:" + sum);
System.out.println("平均分:" + average);
System.out.println("最高分:" + max);
System.out.println("及格人数:" + passCount);
System.out.println("不及格人数:" + failCount);
scanner.close();
}
}
这个案例综合使用了:
Scanner
for
if
else
continue
累加
计数
最大值判断
类型转换
八十、综合案例:ATM 菜单基础版
需求:
1. 查询余额
2. 存款
3. 取款
4. 退出
代码:
import java.util.Scanner;
public class AtmDemo {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
double balance = 1000.0;
boolean running = true;
while (running) {
System.out.println();
System.out.println("===== ATM =====");
System.out.println("1. 查询余额");
System.out.println("2. 存款");
System.out.println("3. 取款");
System.out.println("4. 退出");
System.out.print("请选择操作:");
int choice = scanner.nextInt();
switch (choice) {
case 1:
System.out.println(
"当前余额:" + balance
);
break;
case 2:
System.out.print("请输入存款金额:");
double deposit = scanner.nextDouble();
if (deposit > 0) {
balance += deposit;
System.out.println(
"存款成功,当前余额:" + balance
);
} else {
System.out.println(
"存款金额必须大于 0"
);
}
break;
case 3:
System.out.print("请输入取款金额:");
double withdraw = scanner.nextDouble();
if (withdraw <= 0) {
System.out.println(
"取款金额必须大于 0"
);
} else if (withdraw > balance) {
System.out.println(
"余额不足"
);
} else {
balance -= withdraw;
System.out.println(
"取款成功,当前余额:" + balance
);
}
break;
case 4:
running = false;
System.out.println("已退出系统");
break;
default:
System.out.println(
"请输入正确的操作编号"
);
break;
}
}
scanner.close();
}
}
这个案例虽然还比较基础,但已经包含了很多真实项目中常见的程序流程思想。
八十一、综合案例:登录次数限制
需求:
正确账号:admin
正确密码:123456
最多允许输入 3 次
登录成功立即结束
3 次全部失败后提示账号锁定
代码:
import java.util.Scanner;
public class LoginDemo {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String correctUsername = "admin";
String correctPassword = "123456";
boolean success = false;
for (int i = 1; i <= 3; i++) {
System.out.print("请输入账号:");
String username = scanner.next();
System.out.print("请输入密码:");
String password = scanner.next();
if (correctUsername.equals(username)
&& correctPassword.equals(password)) {
System.out.println("登录成功");
success = true;
break;
} else {
System.out.println(
"账号或密码错误"
);
System.out.println(
"剩余次数:" + (3 - i)
);
}
}
if (!success) {
System.out.println(
"连续登录失败,账号暂时锁定"
);
}
scanner.close();
}
}
这里需要注意:
字符串内容比较通常使用:
equals()
不要简单使用:
==
这一点会在后面的 String 相关内容中详细学习。
八十二、综合案例:数字菜单无限循环
一种常见控制台程序结构:
while (true) {
显示菜单;
接收用户输入;
switch (选择) {
case 1:
执行业务1;
break;
case 2:
执行业务2;
break;
case 0:
退出;
return;
}
}
例如:
import java.util.Scanner;
public class ConsoleSystem {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println();
System.out.println("===== 系统菜单 =====");
System.out.println("1. 查询");
System.out.println("2. 新增");
System.out.println("3. 修改");
System.out.println("4. 删除");
System.out.println("0. 退出");
System.out.print("请输入选项:");
int choice = scanner.nextInt();
switch (choice) {
case 1:
System.out.println("执行查询");
break;
case 2:
System.out.println("执行新增");
break;
case 3:
System.out.println("执行修改");
break;
case 4:
System.out.println("执行删除");
break;
case 0:
System.out.println("程序结束");
scanner.close();
return;
default:
System.out.println("选项错误");
break;
}
}
}
}
这种:
while + switch
结构在早期控制台项目中非常常见。
八十三、break 和 return 的区别
初学时容易把:
break
和:
return
混在一起。
break
结束当前循环或 switch
例如:
while (true) {
break;
}
System.out.println("后面的代码仍然可能执行");
return
在方法中:
直接结束当前方法
例如:
public static void main(String[] args) {
System.out.println("开始");
return;
// 后面的代码无法执行
}
在 main 方法中 return 后:
整个 main 方法结束
程序通常也就结束了。
八十四、本章核心知识总结
选择结构:
if
if-else
if-else if-else
switch
if 适合
范围判断
复杂条件
多个逻辑条件
例如:
if (age >= 18 && age <= 60) {
}
switch 适合
一个值匹配多个固定结果
例如:
星期
月份
菜单编号
状态
循环结构
for
while
do-while
for
适合:
循环次数明确
标准结构:
for (int i = 0; i < 10; i++) {
}
while
适合:
循环次数不明确
主要依赖条件结束
while (条件) {
}
do-while
特点:
至少执行一次
do {
} while (条件);
break
立即结束整个当前循环
continue
跳过本次循环
继续下一轮
嵌套循环
可以简单记:
外层控制整体次数或行数
内层控制每轮具体执行内容