Java 基础语言 ③ ------ 流程控制与数组
-
- 前言
- 一、条件分支
-
- [1.1 if-else 结构](#1.1 if-else 结构)
- [1.2 switch 语句](#1.2 switch 语句)
- 二、循环结构
-
- [2.1 for 循环](#2.1 for 循环)
- [2.2 while 循环](#2.2 while 循环)
- [2.3 do-while 循环](#2.3 do-while 循环)
- [2.4 跳转控制:break 与 continue](#2.4 跳转控制:break 与 continue)
- [2.5 循环嵌套](#2.5 循环嵌套)
- 三、数组
-
- [3.1 一维数组](#3.1 一维数组)
- [3.2 多维数组](#3.2 多维数组)
- [3.3 增强型 for 循环(for-each)](#3.3 增强型 for 循环(for-each))
- 总结

🎬 博主名称: 超级苦力怕
🔥 个人专栏: 《Java 后端修炼手册》《Java 基础语言》
🚀 每一次思考都是突破的前奏,每一次复盘都是精进的开始!
文章元信息:
- 标签:
#Java基础- 建议顺序: 03
- 前置知识: 建议先读《数据类型与运算符》(②)
前言
程序真正的"智能"不在于算得快,而在于能根据条件做决策 、批量处理成千上万条数据 。流程控制赋予程序判断力,数组则提供了批量数据的容器。本文从
if-else和switch的条件分支讲起,一路覆盖for、while、do-while三大循环、break/continue跳转控制,再到一维/多维数组的声明、初始化与遍历,最后掌握增强型for循环------让你告别手写索引的繁琐。适合刚入门 Java 基础、正在刷数组练习题的同学。
一、条件分支
条件分支是程序"做决策"的核心机制------根据布尔表达式的结果,选择不同的执行路径。
1.1 if-else 结构
if 语句通过评估布尔表达式的真假来决定执行哪个代码块。Java 提供了三种 if 使用格式:
格式一:单分支
java
if (关系表达式) {
语句体;
}
执行流程:表达式为 true 执行语句体,为 false 直接跳过。
格式二:双分支
java
if (关系表达式) {
语句体1;
} else {
语句体2;
}
两条路径必走其一。
格式三:多分支(链式调用)
java
if (关系表达式1) {
语句体1;
} else if (关系表达式2) {
语句体2;
} else {
语句体n;
}
从上到下依次判断,一旦命中就不再继续。
✅ 成绩等级判断------多分支典型示例
java
int score = 85;
if (score >= 90 && score <= 100) {
System.out.println("A");
} else if (score >= 80 && score <= 89) {
System.out.println("B");
} else if (score >= 70 && score <= 79) {
System.out.println("C");
} else if (score >= 60 && score <= 69) {
System.out.println("D");
} else if (score >= 0 && score <= 59) {
System.out.println("E");
} else {
System.out.println("成绩不合理");
}
✅ 三角形类型判断------嵌套 if 典型示例
java
// 键盘录入三个边长 a、b、c
if (a + b > c && a + c > b && b + c > a) {
if (a == b && b == c) {
System.out.println("等边三角形");
} else if (a == b || a == c || b == c) {
System.out.println("等腰三角形");
} else if (a * a + b * b == c * c || a * a + c * c == b * b || b * b + c * c == a * a) {
System.out.println("直角三角形");
} else {
System.out.println("普通三角形");
}
} else {
System.out.println("无效三角形");
}
关键细节: 多分支条件下,若多个判断范围有重叠,小范围必须写在大范围上面。比如等边三角形也是等腰三角形,因此等边判断要放在等腰判断之前。
⚠️ 误区:判断布尔变量需要写
if (b == true)正确理解: 布尔类型直接放入小括号即可------
if (b)等价于if (b == true),if (!b)等价于if (b == false)。
⚠️ 误区:if后面加分号无伤大雅正确理解:
if (condition);会被解析为一个空语句体,后面的代码块不再受if控制。这是 C 系语法的经典陷阱。
1.2 switch 语句
switch 是处理单个变量具有多个离散值 时的便捷缩写,比长串 else if 更清晰。
java
switch (表达式) {
case 值1:
语句体1;
break;
case 值2:
语句体2;
break;
default:
语句体n;
break;
}
执行流程:计算表达式值 → 依次匹配 case → 命中后执行对应语句 → 遇到 break 跳出。
✅ 星期运动计划------switch 典型示例
java
Scanner sc = new Scanner(System.in);
int week = sc.nextInt();
switch (week) {
case 1 -> 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("好好吃一顿");
default -> System.out.println("输入错误");
}
JDK 14 正式支持箭头语法(->),省去 break,代码更简洁。
✅ 模拟计算器------switch 表达式返回值
java
int a = 10, b = 20;
String operator = "*";
int result = switch (operator) {
case "+" -> a + b;
case "-" -> a - b;
case "*" -> a * b;
case "/" -> a / b;
default -> 0;
};
System.out.println(result); // 200
| 特性 | if-else |
switch |
|---|---|---|
| 适用场景 | 任意布尔逻辑、范围判断 | 离散值匹配 |
| 支持类型 | 任意布尔表达式 | 整数、字符、字符串、枚举 |
| 不能处理 | --- | 浮点数、对象引用、范围 |
| 代码可读性 | 分支多时较冗长 | 离散值多时更清晰 |
⚠️ 误区:
break会跳出if语句正确理解:
break只对最近的循环或switch有效 ,从未对if生效。1990 年 AT&T 重大事故正是源于程序员误以为break能跳出if,导致全美长途服务瘫痪。
⚠️ 误区:default可有可无正确理解: 防御式编程建议始终保留
default分支,处理所有未预期的输入值。即使最后一个case也保留break,以防后续添加新case时引发坠落。

二、循环结构
循环让程序能够重复执行代码块------处理数组、读取输入、计算累计值,无不依赖循环。
2.1 for 循环
for 循环被视为 while 的语法糖 ,将初始化、条件判断、步进操作集中在一行,适合计数驱动的场景。
java
for (初始化语句; 条件判断语句; 条件控制语句) {
循环体语句;
}
执行顺序:初始化(仅一次)→ 条件判断 → 循环体 → 步进 → 条件判断 → ......
✅ 1~100 偶数和------for 循环典型示例
java
int sum = 0;
for (int i = 2; i <= 100; i += 2) {
sum += i;
}
System.out.println(sum); // 2550
书写技巧: 确定三个要素------开始条件、结束条件、要重复执行的代码。
⚠️ 误区:循环边界条件随便写
正确理解: 边界判断使用
i < n还是i <= n直接影响循环次数。差一错误(Off-by-one)是循环最常见的 Bug,务必明确"第一个索引"和"最后一次执行"。
2.2 while 循环
while 在每次执行前 检查条件,条件为假则一次也不执行。适合不知道循环次数但知道结束条件的场景。
java
初始化语句;
while (条件判断语句) {
循环体;
条件控制语句;
}
✅ 复利翻倍------未知循环次数典型示例
java
double money = 100000; // 本金
int year = 0;
while (money < 200000) { // 结束条件:本金翻倍
money = money + money * 0.017; // 年利率 1.7%
year++;
}
System.out.println(year + " 年后本金翻倍");
✅ 数位之和------while 经典算法
java
int number = 305;
int sum = 0;
while (number != 0) {
sum += number % 10; // 取个位
number = number / 10; // 去掉个位
}
System.out.println(sum); // 8
2.3 do-while 循环
do-while 与上面两种不同:先执行循环体,再判断条件,保证循环体至少执行一次。
java
初始化语句;
do {
循环体;
条件控制语句;
} while (条件判断语句);
适用场景:必须先获取数据(如读取键盘输入)再判断是否继续的场合。
2.4 跳转控制:break 与 continue
break 和 continue 提供了对循环流程的精细控制。
| 关键字 | 作用 | 适用范围 |
|---|---|---|
break |
立即退出最内层循环或 switch |
循环、switch |
continue |
跳过本次迭代剩余代码,进入下一次判断 | 仅循环 |
return |
终止整个方法,返回调用者 | 方法 |
✅ break 示例------找到目标后终止循环
java
for (int i = 1; i <= 5; i++) {
if (i == 3) {
break; // 吃到第 3 个包子,不吃了
}
System.out.println("在吃第" + i + "个包子");
}
// 输出:在吃第1个包子 在吃第2个包子
✅ continue 示例------逢七过
java
for (int i = 1; i <= 100; i++) {
if (i % 10 == 7 || i / 10 % 10 == 7 || i % 7 == 0) {
System.out.println("过");
continue;
}
System.out.println(i);
}
核心要点: 在 for 循环中使用 continue,步进语句依然执行;但在 while 循环中使用 continue,若跳过了计数器更新(如 i++),可能导致死循环。
⚠️ 误区:循环中应完全避免使用
break正确理解: 在"循环加一半"(Time and a half loop)场景中,用
break从循环中间退出,比为了规避break而在循环前后复制相同逻辑更优雅、更易维护。
2.5 循环嵌套
循环嵌套即循环里面还有循环------外循环控制"行",内循环控制"列"。
✅ 九九乘法表------嵌套循环典型示例
java
for (int i = 1; i <= 9; i++) { // 外循环:9 行
for (int j = 1; j <= i; j++) { // 内循环:第 i 行有 i 列
System.out.print(j + "*" + i + "=" + (i * j) + "\t");
}
System.out.println(); // 换行
}
| 循环类型 | 判断时机 | 最少执行次数 | 典型场景 |
|---|---|---|---|
for |
先判断 | 0 | 已知循环次数/范围 |
while |
先判断 | 0 | 未知次数,已知结束条件 |
do-while |
后判断 | 1 | 至少执行一次再判断 |
💡 核心结论: 知道循环次数用 for,知道结束条件但不知道次数用 while,至少执行一次用 do-while。

三、数组
数组是一种容器 ,用于存储同种数据类型的多个值。数组一旦创建,长度不可改变。
3.1 一维数组
静态初始化(已知元素值)
java
// 完整格式
int[] arr1 = new int[]{11, 22, 33};
// 简化格式(最常用)
int[] arr2 = {1, 2, 3, 4, 5};
String[] names = {"zhangsan", "lisi", "wangwu"};
动态初始化(已知长度,元素待定)
java
int[] ages = new int[3]; // 默认值均为 0
double[] scores = new double[10]; // 默认值均为 0.0
默认初始化值:
| 数组类型 | 默认值 |
|---|---|
整数(byte/short/int/long) |
0 |
浮点(float/double) |
0.0 |
布尔(boolean) |
false |
字符(char) |
'' |
引用类型(如 String) |
null |
索引访问: 索引从 0 开始,连续不间断,逐个 +1 增长。最大索引 = 数组长度 - 1。
java
int[] arr = {1, 2, 3, 4, 5};
int value = arr[3]; // 获取索引 3 的值 → 4
arr[3] = 10; // 修改索引 3 的值为 10
数组遍历(传统 for)
java
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
✅ 求数组最大值------经典数组算法
java
int[] arr = {33, 5, 22, 44, 55};
int max = arr[0]; // 注意:max 必须初始化为数组元素,不能设为 0
for (int i = 1; i < arr.length; i++) {
if (max < arr[i]) {
max = arr[i];
}
}
System.out.println(max); // 55
⚠️ 误区:数组的最大索引就是
arr.length正确理解: 最大索引是
arr.length - 1。访问arr[arr.length]会抛出ArrayIndexOutOfBoundsException。
3.2 多维数组
多维数组本质是数组的数组------每个元素本身又是一个数组。
二维数组声明与初始化
java
// 静态初始化
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// 动态初始化(指定行数,列数可后续确定)
int[][] grid = new int[3][4]; // 3 行 4 列,所有元素默认 0
// 不规则二维数组(每行列数不同)
int[][] jagged = new int[3][];
jagged[0] = new int[2]; // 第 0 行 2 列
jagged[1] = new int[4]; // 第 1 行 4 列
jagged[2] = new int[3]; // 第 2 行 3 列
二维数组遍历
java
for (int i = 0; i < matrix.length; i++) { // 外层:行
for (int j = 0; j < matrix[i].length; j++) { // 内层:列
System.out.print(matrix[i][j] + " ");
}
System.out.println();
}
✅ 两数之和------双层循环遍历数组
java
int[] nums = {2, 7, 11, 15};
int target = 9;
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++) {
if (nums[i] + nums[j] == target) {
System.out.println(i + ", " + j); // 0, 1
break;
}
}
}
3.3 增强型 for 循环(for-each)
增强型 for 循环是 Java 提供的语法糖,直接访问内容而非索引,消除了手动管理索引和边界的需要,减少差一错误。
java
for (数据类型 变量名 : 数组或集合) {
// 使用变量名访问当前元素
}
✅ 增强型 for 遍历数组
java
int[] arr = {1, 2, 3, 4, 5};
for (int num : arr) {
System.out.println(num); // 依次输出每个元素的值
}
✅ 增强型 for 遍历二维数组
java
int[][] matrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
for (int[] row : matrix) { // 外层取出一维数组
for (int val : row) { // 内层取出具体数值
System.out.print(val + " ");
}
System.out.println();
}
| 特性 | 传统 for 循环 |
增强型 for 循环 |
|---|---|---|
| 需要索引 | 是 | 否 |
| 可修改元素 | 是(通过索引赋值) | 否(变量是副本) |
| 支持逆序遍历 | 是 | 否 |
| 适用范围 | 数组、需要索引的场景 | 数组、所有 Iterable 集合 |
| 差一错误风险 | 有 | 无 |
⚠️ 误区:增强型
for可以修改数组元素正确理解: 增强型
for的循环变量是元素值的副本 ,修改它不影响原数组。要修改数组元素,必须使用传统for循环配合索引。
⚠️ 误区:增强型for的变量可以在循环外声明正确理解: 变量/迭代器必须在
for语句内部声明,否则编译器报错。这种设计将变量作用域严格限制在循环块内,增强了局部安全性。

总结
| 知识点 | 核心要点 |
|---|---|
| if-else | 三种格式(单/双/多分支),小范围写上面,布尔变量直接放括号 |
| switch | 离散值匹配,注意 break 防坠落,JDK 14 支持箭头语法和表达式返回值 |
| for 循环 | 计数驱动,适合已知次数/范围,注意边界差一错误 |
| while 循环 | 先判断后执行,适合已知结束条件、未知次数 |
| do-while | 先执行后判断,至少执行一次 |
| break/continue | break 退出循环,continue 跳过本次;for 中 continue 后步进仍执行,while 中可能死循环 |
| 一维数组 | 静态/动态初始化,索引从 0 开始,length 获取长度,最大索引 = length - 1 |
| 二维数组 | 数组的数组,可有不规则行,双层循环遍历 |
| 增强型 for | 直接访问内容,不操作索引,变量作用域仅限循环内,不能修改原数组元素 |
💡 核心结论: 流程控制赋予程序判断力,数组提供批量数据的容器。if-else 处理范围判断,switch 处理离散值匹配;for 适合已知次数,while 适合已知结束条件;数组的静态初始化用于已知元素、动态初始化用于已知长度;遍历数组时优先使用增强型 for 提升可读性,但需要修改元素时必须回归传统 for。
💡 关键提醒: 始终警惕循环边界的差一错误,牢记 break 只对循环/switch 有效,switch 中保留 default 和 break 是最基本的防御式编程习惯。
