【Java零基础30天挑战·Day5】程序的十字路口:一文彻底搞懂分支结构(if & switch)
程序的十字路口:一文彻底搞懂分支结构(if & switch)
📝 前言:在程序的世界里,代码并不总是从上到下一成不变地“直线奔跑”。很多时候,程序需要根据不同的情况做出不同的选择,就像我们走到十字路口需要根据红绿灯决定是走是停一样。这就是今天我们要探讨的核心——分支结构(选择结构)。
本文将从最基础的if语句出发,一路打怪升级到switch,并分享一些日常开发中的避坑经验和代码规范。干货满满,建议收藏!⭐
🌟 一、 什么是分支结构?
在编程中,三大基本结构分别是:顺序结构、分支结构、循环结构。
- 顺序结构:代码从上到下依次执行(默认情况)。
- 分支结构:根据条件判断的结果,选择性地执行某段代码。
分支结构的灵魂在于条件判断,在Java/C等语言中,条件表达式的结果必须是一个布尔值(true 或 false)。
🛤️ 二、 if 分支家族
if家族是最常用的分支结构,它有三种形态:单分支、双分支、多分支。
1. 单分支:如果…就… (if)
当你只有一个条件需要满足时使用。满足就执行,不满足就跳过。
// 语法
if (条件表达式) {
// 条件为 true 时执行的代码
}
// 示例:如果下雨,就带伞
boolean isRaining = true;
if (isRaining) {
System.out.println("外面下雨了,记得带伞!");
}
2. 双分支:如果…否则… (if-else)
非黑即白的选择。条件满足走A逻辑,不满足走B逻辑。
// 语法
if (条件表达式) {
// 条件为 true 时执行
} else {
// 条件为 false 时执行
}
// 示例:判断奇偶数
int num = 10;
if (num % 2 == 0) {
System.out.println(num + "是偶数");
} else {
System.out.println(num + "是奇数");
}
3. 多分支:如果…否则如果…否则… (if - else if - else)
面对多个条件判断时,按顺序从上往下判断,只要有一个条件满足,执行完毕后就会跳出整个if结构。
// 语法
if (条件1) {
// 满足条件1执行
} else if (条件2) {
// 满足条件2执行
} else if (条件3) {
// 满足条件3执行
} else {
// 以上条件都不满足时执行(可省略,但建议保留作为兜底逻辑)
}
// 示例:成绩评级
int score = 85;
if (score >= 90) {
System.out.println("优秀");
} else if (score >= 80) {
System.out.println("良好"); // 执行这里后,直接跳出整个if
} else if (score >= 60) {
System.out.println("及格");
} else {
System.out.println("不及格");
}
⚠️ 避坑指南1:
else if的顺序非常重要!如果把上面例子中score >= 60放在第一个判断,那么85分也会被判定为“及格”。多分支判断必须注意条件之间的互斥性和顺序。
🔀 三、 switch 分支:精准匹配
当你需要对一个具体的值进行多路匹配时,switch比if-else if看起来更清爽。
1. 基本语法与示例
// 示例:根据星期几输出日程
int day = 3;
switch (day) {
case 1:
System.out.println("周一:开会");
break;
case 2:
System.out.println("周二:写代码");
break;
case 3:
System.out.println("周三:改Bug"); // 匹配成功
break;
// ...省略其他天
default:
System.out.println("休息日");
break;
}
2. switch 的三大铁律
- 支持的类型:在Java中,
switch支持byte, short, int, char, String(Java7+), 枚举。不支持long, float, double及boolean。 break不能忘:如果漏写了break,会发生穿透现象(Fall-through),程序会无条件执行后续的case代码,直到遇到break为止。default的位置:default可以放在任何位置,但习惯上放在最后。它的作用类似于if-else中的else。
💡 巧妙利用穿透:有时候穿透不是Bug而是Feature!比如判断季节:
int month = 5;
switch (month) {
case 3: case 4: case 5:
System.out.println("春季");
break;
case 6: case 7: case 8:
System.out.println("夏季");
break;
// ...
}
⚔️ 四、 if vs switch:到底用哪个?
| 比较维度 | if-else | switch |
|---|---|---|
| 判断条件 | 布尔表达式(范围、大小判断) | 具体的常量值(等值判断) |
| 适用场景 | 区间判断、复杂逻辑判断 | 离散值的多路匹配(如菜单选择、星期) |
| 底层效率 | 逐条判断,效率逐渐降低 | 底层通过跳转表实现,效率恒定(JVM优化) |
| 代码可读性 | 嵌套过多时容易变成“波纹状” | 结构清晰,一目了然 |
总结口诀:
- 等值判断用
switch,区间判断用if。 - 能用
switch的场景一定能用if,反之不然。
🚀 五、 进阶:如何写出优雅的分支代码?
在实际开发中,嵌套过深的 if-else 被称为“箭头代码”(缩进越来越深,形如箭头 >),极其难以阅读。这里分享两个优化技巧:
1. 卫语句提前返回
反面教材:
public void process(Order order) {
if (order != null) {
if (order.isPaid()) {
if (order.hasStock()) {
// 核心业务逻辑(嵌套太深)
System.out.println("开始发货...");
} else {
System.out.println("库存不足");
}
} else {
System.out.println("订单未支付");
}
} else {
System.out.println("订单不存在");
}
}
优化后(提前Return,拒绝嵌套):
public void process(Order order) {
if (order == null) {
System.out.println("订单不存在");
return; // 提前阻断
}
if (!order.isPaid()) {
System.out.println("订单未支付");
return;
}
if (!order.hasStock()) {
System.out.println("库存不足");
return;
}
// 核心业务逻辑(只有一层缩进,清爽!)
System.out.println("开始发货...");
}
2. 永远加上大括号 {}!
哪怕 if 里面只有一行代码,也必须加上 {}。这不仅是为了规范,更是为了防止后续维护时添加代码造成的逻辑错误(著名的苹果SSL漏洞就是这么来的)。
// 极度危险!不要这样写!
if (condition)
doSomething();
// 规范写法
if (condition) {
doSomething();
}
🎯 总结
if是分支结构的主力,适用于所有条件判断;switch是等值匹配的利器,注意别忘了break。- 多分支
if-else if要注意条件顺序;switch不支持浮点型和长整型。 - 实际开发中,要警惕深层嵌套,使用卫语句提前
return优化代码结构。 - 好习惯:永远写上大括号
{}!
💬 互动时间:你在开发中遇到过最离谱的
if-else嵌套有几层?欢迎在评论区吐槽分享!如果觉得本文对你有帮助,别忘了点赞👍 + 关注❤️哦!
💡 给你的发布小贴士(发布前必看):
- 替换代码语言:如果你主要写C/C++,把代码块里的
java换成c,把System.out.println换成printf,把boolean换成bool即可。 - 封面图:在CSDN发布时,加一张好看的封面图(比如一个岔路口的图片,或者代码截图)会大大增加点击率。
- 标签设置:在CSDN发布时,添加标签:
Java基础、初学者、分支结构、if-else、编程思维,有助于获得更多系统推荐流量。
用户_jWywoW
我现在还要写一篇关于循环结构的csdn
思考结束
太棒了!写完分支结构,紧接着写循环结构,这两篇完全可以作为你的“程序控制流系列”博客,风格上我也帮你保持了统一,依然是用通俗易懂的比喻 + 代码示例 + 避坑指南的模式。
这篇以Java语法为基准(C/C++高度兼容,Python/Go等逻辑一致),直接复制即可发布!
标题建议(选一个你喜欢的):
- 拒绝重复造轮子!一文彻底搞懂循环结构
- 【Java基础】循环结构详解——for、while与do-while的相爱相杀
- 程序的“永动机”:掌握循环结构,看这篇就够了!
正文内容:
拒绝重复造轮子!一文彻底搞懂循环结构
📝 前言:在上一篇《程序的十字路口:一文搞懂分支结构》中,我们学会了如何让程序做选择。但现实世界中,很多时候我们需要重复做某件事,比如跑圈、比如批量处理数据。如果每次都把代码复制粘贴,不仅让代码臃肿不堪,维护起来更是灾难。这就是今天的主角——循环结构出场的时刻!
循环是计算机最擅长的能力(毕竟它本来就是个不知疲倦的机器)。本文将带你全面拆解三大循环语法,并分享如何写出高效、优雅的循环代码。🚀
🔄 一、 循环的本质:四要素
无论哪种循环语言,其核心都离不开这四个要素:
- 初始化语句:在循环开始前执行,通常用来定义循环变量(如
int i = 0)。 - 条件判断:决定循环是否继续执行,结果必须是布尔值(如
i < 10)。 - 循环体:需要重复执行的代码逻辑。
- 迭代语句(步进):每次循环后改变循环变量,让循环趋近于结束(如
i++)。
⚠️ 致命陷阱:如果缺少“迭代语句”或“条件判断永远为true”,程序就会陷入死循环,犹如脱缰的野马永远跑不停!
🏃♂️ 二、 三大循环语句
1. for 循环:精准控制的计数器
当你明确知道循环要执行多少次时,首选 for 循环。它的四要素最集中,一目了然。
// 语法:四要素一行搞定
for (初始化语句; 条件判断; 迭代语句) {
// 循环体
}
// 示例:打印 1 到 5
for (int i = 1; i <= 5; i++) {
System.out.println("当前是第 " + i + " 次循环");
}
执行顺序(面试常考):
① 初始化语句 -> ② 条件判断 -> ③ 循环体 -> ④ 迭代语句 -> ② 条件判断 -> ③ 循环体 -> … 直到条件为 false 退出。
2. while 循环:谨慎的侦察兵
当你不确定循环多少次,只知道满足某个条件就继续时,用 while。它是“先判断,后执行”,如果一开始条件就不满足,循环体一次都不会执行!
// 语法
初始化语句;
while (条件判断) {
// 循环体;
迭代语句; // 千万别忘了!
}
// 示例:折纸问题,一张纸厚0.1mm,对折多少次能超过珠穆朗玛峰(8848860mm)?
double thickness = 0.1;
int count = 0;
while (thickness < 8848860) {
thickness *= 2; // 对折
count++; // 记录次数
}
System.out.println("需要折叠 " + count + " 次"); // 结果:27次
3. do-while 循环:先斩后奏的实干家
它和 while 的唯一区别是:先执行一次循环体,再判断条件。也就是说,无论条件是否满足,循环体至少会执行一次。
// 语法
初始化语句;
do {
// 循环体;
迭代语句;
} while (条件判断); // ⚠️ 注意这里的分号千万不能丢!
// 示例:密码验证,至少需要输入一次
Scanner sc = new Scanner(System.in);
String password;
do {
System.out.println("请输入密码:");
password = sc.nextLine();
} while (!"123456".equals(password)); // 不是123456就继续输
System.out.println("密码正确,登录成功!");
⚔️ 三、 循环界的红黄牌:break 与 continue
循环就像一条环形跑道,而 break 和 continue 就是跑道上的出口和跳板。
| 关键字 | 作用 | 形象比喻 |
|---|---|---|
| break | 结束整个循环,跳出到循环外的代码 | 玩游戏直接拔电源 / 跑步直接离场 |
| continue | 跳过本次循环,直接进入下一次循环迭代 | 跑步跨过某一圈 / 玩游戏跳过当前关卡 |
// break 示例:找到数字 5 就停止寻找
for (int i = 1; i <= 10; i++) {
if (i == 5) {
System.out.println("找到了5,下班!");
break; // 整个for循环直接结束,6-10都不会打印
}
System.out.println("正在寻找..." + i);
}
// continue 示例:逢7过(7的倍数不打印)
for (int i = 1; i <= 10; i++) {
if (i % 7 == 0) {
continue; // 跳过本次打印,直接执行 i++ 进入下一轮
}
System.out.println("当前数字:" + i);
}
🍬 四、 语法糖:增强型 for 循环
在遍历数组或集合时,如果不需要操作索引,强烈推荐使用增强型 for 循环(也叫 for-each 循环)。它简洁且不易出错。
int[] nums = {10, 20, 30, 40};
// 传统 for 循环
for (int i = 0; i < nums.length; i++) {
System.out.println(nums[i]);
}
// 增强 for 循环(读作:从 nums 中依次取出每个 num)
for (int num : nums) {
System.out.println(num);
}
⚠️ 注意:
for-each无法获取当前索引,也不能在循环中修改数组/集合元素的值(对于基本类型),它只适合纯粹的“遍历读取”。
🚀 五、 进阶:循环优化与避坑指南
日常开发中,循环往往是性能瓶颈的重灾区。掌握以下技巧,让你的代码从“能跑”变成“跑得快”:
1. 避免在循环内部频繁创建对象
每次循环都 new 一个新对象,不仅消耗内存,还会增加垃圾回收(GC)的压力。
// ❌ 反例:每次循环都创建新对象
for (int i = 0; i < 10000; i++) {
Date date = new Date(); // 极度浪费
System.out.println(date);
}
// ✅ 正例:在循环外创建,循环内复用
Date date = new Date();
for (int i = 0; i < 10000; i++) {
date.setTime(System.currentTimeMillis()); // 修改状态即可
System.out.println(date);
}
2. 将耗时的计算移到循环外
不要让循环做无用的重复计算!
// ❌ 反例:list.size() 每次循环都要计算一次
for (int i = 0; i < list.size(); i++) { ... }
// ✅ 正例:提前算好,用常量接收
int len = list.size();
for (int i = 0; i < len; i++) { ... }
3. 尽量减少循环嵌套的层数
双层循环的时间复杂度是 O(n²),数据量一大,程序直接卡死。如果业务允许,尝试通过 Map 空间换时间 来减少嵌套。
// ❌ 反例:找两个列表的交集,双层嵌套,O(n²)
for (String s1 : list1) {
for (String s2 : list2) {
if (s1.equals(s2)) { ... }
}
}
// ✅ 正例:用 HashSet 降维打击,O(n)
Set<String> set = new HashSet<>(list2);
for (String s1 : list1) {
if (set.contains(s1)) { ... } // 查找复杂度降为 O(1)
}
🎯 总结
- 明确次数用
for,不明次数用while,至少一次用do-while。 break彻底退出,continue跳过本轮。- 遍历数组/集合优先考虑
for-each,简洁优雅。 - 循环优化三大法:少创建对象、少重复计算、用Map降维减嵌套。
循环是编程中最具魔力的结构,掌握它,你就掌握了让计算机为你“不知疲倦地打工”的秘密武器!
💬 互动时间:你在写循环时遇到过最头疼的Bug是什么?是死循环烧干CPU,还是数组越界?欢迎在评论区分享你的“血泪史”!如果觉得有收获,别忘了点赞👍 + 收藏⭐,下期见!
更多推荐

所有评论(0)