日期:2026-07-15
项目:c260715
作者:WanJL
switch 语句和 if 不同,if 是范围的匹配,而 switch 是针对某个具体值的匹配。
switch (变量) {
case 常量1:
代码块;
break;
case 常量2:
代码块;
break;
case 常量n:
代码块;
break;
default:
代码块;
}
执行流程:
case 常量1 相等,就执行对应的代码块case 常量n 相等,就执行对应代码块default 中的代码块break 的作用:在执行完对应的代码块后,跳出整个 switch 结构,后面的代码不再执行int a = 3;
switch (a) {
case 1:
System.out.println("a=1");
break;
case 2:
System.out.println("a=2");
break;
case 3:
System.out.println("a=3");
break;
default:
System.out.println("不知道");
}
// 输出:a=3
定义一个变量(1~7),使用 switch 判断并分别输出 星期一 ~ 星期日。
int b = 3;
switch (b) {
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("不知道");
}
JDK 17~21 引入了增强的 switch 语句,支持:
->:更简洁,自带 break 效果(不需要显式写 break)String day = "1";
switch (day) {
case "1", "2", "3", "4", "5" -> System.out.println("工作日");
case "6", "7" -> System.out.println("休息日");
}
switch (day) {
case "1" -> {
System.out.println("星期一");
System.out.println("周一");
System.out.println("天不错");
}
case "2" -> System.out.println("星期二");
case "3" -> System.out.println("星期三");
case "4" -> System.out.println("星期四");
case "5" -> System.out.println("星期五");
case "6" -> System.out.println("星期六");
case "7" -> System.out.println("星期日");
}
如果箭头右侧有多条语句,需要使用
{ }代码块包裹。
switch 可以直接作为一个表达式使用,返回匹配到的值,可用于赋值等操作:
String dd = "1";
String s = switch (dd) {
case "1" -> "星期一";
case "2" -> "星期二";
case "3" -> "星期三";
case "4" -> "星期四";
case "5" -> "星期五";
case "6" -> "星期六";
case "7" -> "星期日";
default -> "不知道";
};
System.out.println("今天是" + s + ",天气真不错");
// 输出:今天是星期一,天气真不错
⚠️ switch 表达式必须要有
default分支,以确保所有可能值都有对应结果。
| 特性 | 传统 switch | 增强 switch(JDK 17+) |
|---|---|---|
| 语法 | case 值: + break; |
case 值 -> 箭头语法 |
| break | 必须写,否则穿透 | 自带 break,无需写 |
| 多值匹配 | 不支持(需写多个 case) | 支持:case "1","2" -> |
| 返回值 | 不支持 | 支持:switch(expr) { ... } |
| 穿透效果 | 有(可利用) | 无 |
| 可读性 | 一般 | 更简洁清晰 |
循环结构:满足条件就不停地重复执行某段代码。
Java 提供三种循环结构:
| 循环类型 | 特点 |
|---|---|
for 循环 |
先判断,后执行;适用于已知循环次数 |
while 循环 |
先判断,后执行;适用于不确定循环次数 |
do...while 循环 |
先执行,后判断;循环体至少执行一次 |
for (初始化语句; 循环条件; 迭代语句) {
循环体;
}
第1步:执行初始化语句(如 int i = 0;)
第2步:执行循环条件(如 i < 10;)
→ 如果结果为 true,执行第3步
→ 如果结果为 false,跳转到第5步(结束循环)
第3步:执行循环体(如 System.out.println(i);)
第4步:执行迭代语句(如 i++),然后跳转回第2步
第5步:跳出循环,继续执行后面的代码
for (int i = 1; i <= 100; i++) {
System.out.println(i);
}
初始化语句;
while (循环条件) {
循环体;
迭代语句;
}
int i = 1;
while (i <= 100) {
System.out.println(i);
i++;
}
⚠️ 重要:使用
while或do...while时,一定不要忘了写迭代语句(如i++),否则会变成死循环(无限循环)。
初始化语句;
do {
循环体;
迭代语句;
} while (循环条件);
int i = 1;
do {
System.out.println(i);
i++;
} while (i <= 100);
| 特性 | for |
while |
do...while |
|---|---|---|---|
| 判断时机 | 先判断,后执行 | 先判断,后执行 | 先执行,后判断 |
| 执行次数 | 0~n 次 | 0~n 次 | 至少 1 次 |
| 适用场景 | 已知循环次数 | 不确定循环次数 | 至少需要执行一次 |
| 初始化位置 | for 语句内部 | 循环外部 | 循环外部 |
Java 提供了三种方式控制循环的执行流程:
| 控制语句 | 作用 | 说明 |
|---|---|---|
break |
结束整个循环 | 跳出循环体,继续执行循环后面的代码 |
continue |
结束本轮循环 | 跳过本次循环剩余代码,继续执行下一轮循环 |
return |
结束整个方法 | 直接结束当前方法,方法中循环后面的代码也不再执行 |
for (int i = 0; i < 10; i++) {
if (i == 3) {
break; // i == 3 时结束整个循环
}
System.out.println(i);
}
// 输出:0 1 2
// 循环到此结束,继续执行循环外的代码
System.out.println(".....循环后的代码....");
break执行后,循环立即终止,程序继续执行循环后面的代码。
for (int i = 0; i < 10; i++) {
if (i == 3) {
continue; // i == 3 时跳过本轮,不执行输出
}
System.out.println(i);
}
// 输出:0 1 2 4 5 6 7 8 9
// 注意:没有 3,因为 i==3 时跳过了本次循环
continue执行后,本轮循环中剩余的代码不再执行,直接进入下一轮迭代(i++ → 判断条件)。
for (int i = 0; i < 10; i++) {
if (i == 3) {
return; // i == 3 时结束方法,循环后面的代码也不执行了
}
System.out.println(i);
}
// 输出:0 1 2
// 注意:循环后面的所有代码都不会执行
System.out.println(".....循环后的代码...."); // ❌ 不会执行
return比break更"狠"——它不仅结束循环,还会直接结束整个main方法,方法内循环后面的所有代码都不再执行。
| 控制语句 | 影响范围 | 循环剩余代码 | 循环外代码 | 适用场景 |
|---|---|---|---|---|
break |
仅当前循环 | 不执行 | 继续执行 | 找到目标后提前退出循环 |
continue |
仅本轮循环 | 不执行(跳到下一轮) | 继续执行 | 跳过某些不符合条件的值 |
return |
整个方法 | 不执行 | 不执行 | 方法执行完毕或异常提前返回 |
double a = 0.1 + 0.2;
System.out.println(a); // 0.30000000000000004
if (a == 0.3) {
System.out.println("相等");
} else {
System.out.println("不想等");
}
// 输出:不想等
原因:浮点数采用 IEEE 754 标准存储,
0.1 + 0.2在计算机中无法精确表示为0.3,而是近似值0.30000000000000004。
int x = 2;
switch (x) {
case 1:
case 2:
case 3:
System.out.println("1~3");
break;
}
// 输出:1~3
// 如果 case 1、case 2 不加 break,会一直穿透到 case 3
穿透技巧:当多个 case 需要执行相同的代码时,可以利用穿透特性,只在最后一个 case 写
break,减少重复代码。
给定一个整数 12345,使用 while 循环统计它有多少位。
/**
* @author WanJl
* @title Demo04
* @description 课堂练习:统计整数位数
* @create 2026/7/15
*/
public class Demo04 {
public static void main(String[] args) {
int n = 12345;
int t = 0; // 统计位数
while (n != 0) {
n /= 10; // 每次除以10,缩小10倍
t++; // 每缩小一次,位数累计1
}
System.out.println(t); // 输出:5
}
}
核心思路:一个整数不断除以 10,每除一次就去掉一位,直到变成 0。除的次数就是位数。
for vs while 选择原则:知道循环次数用
for,不知道循环次数用while。此处我们不知道12345是多少位(不确定除以多少次才到 0),所以适合用while。
给定一个整数 12345,使用 while 循环求其各位数字之和(1 + 2 + 3 + 4 + 5 = 15)。
/**
* @author WanJl
* @title Demo05
* @description 课堂练习:求各位数字之和
* @create 2026/7/15
*/
public class Demo05 {
public static void main(String[] args) {
int n = 12345;
int sum = 0; // 累加和
while (n != 0) {
sum += n % 10; // 获取个位数字,累加到 sum
n /= 10; // 去掉个位,缩小10倍
}
System.out.println(sum); // 输出:15
}
}
核心思路:
n % 10— 每次取个位数字n / 10— 去掉个位,继续取下一个数字- 循环直到
n变成 0
嵌套循环就是循环里面再放一个循环。
for (int i = 0; i < 10; i++) { // 外层循环
System.out.println("i=" + i);
for (int j = 0; j < 10; j++) { // 内层循环
System.out.print("j=" + j);
}
System.out.println();
}
执行规律:外层循环执行一轮,内层循环完整执行一次。
内层循环总共执行的次数 = 外层循环次数 × 内层循环次数
/**
* @author WanJl
* @title Demo06
* @description 课堂练习:打印4行5列矩形星号
* @create 2026/7/15
*/
public class Demo06 {
public static void main(String[] args) {
for (int i = 0; i < 4; i++) { // 外层:控制行数
for (int j = 0; j < 5; j++) { // 内层:控制每行星号个数
System.out.print("*"); // 不换行
}
System.out.println(); // 一行结束,换行
}
}
}
// 输出:
// *****
// *****
// *****
// *****
/**
* @author WanJl
* @title Demo07
* @description 课堂练习:打印5行5列空心矩形星号
* @create 2026/7/15
*/
public class Demo07 {
public static void main(String[] args) {
for (int i = 1; i <= 5; i++) { // 外层:控制行数
for (int j = 1; j <= 5; j++) { // 内层:控制列数
// 第1行、第5行:全部输出 *
// 第2~4行:第1列和第5列输出 *,其余输出空格
if (i == 1 || i == 5) {
System.out.print("*");
} else {
if (j == 1 || j == 5) {
System.out.print("*");
} else {
System.out.print(" ");
}
}
}
System.out.println(); // 换行
}
}
}
// 输出:
// *****
// * *
// * *
// * *
// *****
/**
* @author WanJl
* @title Demo08
* @description 课堂练习:打印5行菱形星号图案
* @create 2026/7/15
*/
public class Demo08 {
public static void main(String[] args) {
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= 5; j++) {
if (i == 3) { // 第3行:全星号
System.out.print("*");
} else {
if (i == 1 || i == 5) { // 第1、5行:中间星号
if (j == 3) {
System.out.print("*");
} else {
System.out.print(" ");
}
} else if (i == 2 || i == 4) { // 第2、4行:两侧星号
if (j == 1 || j == 5) {
System.out.print(" ");
} else {
System.out.print("*");
}
}
}
}
System.out.println();
}
}
}
// 输出:
// *
// ***
// *****
// ***
// *
嵌套循环 + 条件判断是解决二维图形打印问题的核心思路:
- 外层循环控制行数
- 内层循环控制列数
if判断决定某个位置输出*还是空格
数组是一种用来存储多个相同类型数据的容器。
Java 中的数据类型分为两类: | 类型 | 说明 | |------|------| | 基本数据类型 | byte、short、int、long、float、double、char、boolean | | 引用数据类型 | 类(class)、数组([])、接口(interface)、枚举(enum)、注解(@interface) |
之前学过的
String就是引用数据类型(类),现在学习的数组也是引用数据类型。
| 特点 | 说明 |
|---|---|
| ① 连续存储 | 数组中的每个元素(值)存储在连续的内存空间中 |
| ② 通过索引访问 | 使用索引值(下标)来访问数组中的元素 |
| ③ 固定长度 | 数组有一个 length 属性,表示数组的长度,创建后不能改变 |
| ④ 同类型 | 数组中只能存储同一种类型的元素 |
| ⑤ 指定类型 | 创建数组时必须指定要存储的元素类型 |
| ⑥ 索引从 0 开始 | 第一个元素的索引为 0,最后一个元素的索引为 length - 1 |
数据类型[] 数组名;
示例:
int[] a; // 声明一个 int 类型的数组变量 a
int[] a表示a是一个 int 类型的数组变量,为它赋值时对应的数组必须是整数类型。
数组的初始化分为两种方式:动态初始化 和 静态初始化。
程序员负责定义数组长度,计算机负责为数组元素赋默认值。
// 语法:数组变量名 = new 数组类型[数组长度];
int[] a = new int[10];
各类型元素的默认值:
| 元素类型 | 默认值 |
|---------|-------|
| byte、short、int、long | 0 |
| float、double | 0.0 |
| char |