Java选择语句和循环语句

O泡李华 10

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

跳过本次循环
继续下一轮

嵌套循环

可以简单记:

外层控制整体次数或行数

内层控制每轮具体执行内容