Java 基础语言 ③:流程控制与数组——从条件分支到数组遍历,一篇通关

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 基础语言》

🚀 每一次思考都是突破的前奏,每一次复盘都是精进的开始!


文章元信息:

前言

程序真正的"智能"不在于算得快,而在于能根据条件做决策批量处理成千上万条数据 。流程控制赋予程序判断力,数组则提供了批量数据的容器。本文从 if-elseswitch 的条件分支讲起,一路覆盖 forwhiledo-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

breakcontinue 提供了对循环流程的精细控制。

关键字 作用 适用范围
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 跳过本次;forcontinue 后步进仍执行,while 中可能死循环
一维数组 静态/动态初始化,索引从 0 开始,length 获取长度,最大索引 = length - 1
二维数组 数组的数组,可有不规则行,双层循环遍历
增强型 for 直接访问内容,不操作索引,变量作用域仅限循环内,不能修改原数组元素

💡 核心结论: 流程控制赋予程序判断力,数组提供批量数据的容器。if-else 处理范围判断,switch 处理离散值匹配;for 适合已知次数,while 适合已知结束条件;数组的静态初始化用于已知元素、动态初始化用于已知长度;遍历数组时优先使用增强型 for 提升可读性,但需要修改元素时必须回归传统 for

💡 关键提醒: 始终警惕循环边界的差一错误,牢记 break 只对循环/switch 有效,switch 中保留 defaultbreak 是最基本的防御式编程习惯。

相关推荐
funnycoffee1231 小时前
Cisco Firewpower 4100 9300 FXOS change management ip address
linux·数据库·tcp/ip
2501_921939261 小时前
MySQL(备份恢复、主从复制读写分离)
数据库·mysql
阿kun要赚马内1 小时前
SQLAlchemy的类型定义语法
数据库·oracle
深度学习lover1 小时前
<数据集>yolo 车牌识别<目标检测>
人工智能·python·yolo·目标检测·计算机视觉·车牌识别
luck_bor1 小时前
Lambda表达式 算法异常
java·开发语言
码上小翔哥1 小时前
Jackson 配置深度解析
java·后端
范范@1 小时前
day2-python基础语法
开发语言·python
qq_2518364571 小时前
基于java 私厨美食共享平台系统设计与实现(有源码)
java·开发语言·美食
编码者卢布1 小时前
【Azure Container App】容器应用的维护窗口设置
python·azure