第6章 循环控制:for / while / do-while

发布时间:2026/8/18 11:16:00
第6章 循环控制:for / while / do-while 第6章 循环控制for / while / do-while计算机最擅长的就是重复劳动。本节学习三种循环语句for、while、do-while以及 break 和 continue 两个控制关键字。一、for 循环语法结构for(初始化;条件判断;步进){// 循环体}for(inti1;i5;i){System.out.println(第 i 次循环);}执行流程初始化int i 1只执行一次条件判断i 5为 true 继续为 false 退出执行循环体打印步进i回到第 2 步for 循环适合循环次数确定的场景比如遍历数组、计数。常用变体// 倒序for(inti10;i1;i--){System.out.println(i);}// 步进为 2打印偶数for(inti2;i10;i2){System.out.println(i);}// 循环变量在循环外定义循环结束后还能用inti;for(i0;i10;i){// ...}System.out.println(i);// 10能拿到循环结束后的值补充循环变量声明在 for 括号里时作用域只限循环内循环外访问会编译报错for 的三个部分都可省略for (;;)是死循环的一种写法见死循环小节。二、while 循环while(条件){// 循环体}先判断后执行。条件为 false 时一次都不执行。inti1;while(i5){System.out.println(i);i;// 别忘了改变循环条件否则死循环}while 适合循环次数不确定的场景比如一直读取输入直到输入结束、随机猜数。// 典型场景不断读取用户输入输入 0 结束需 import java.util.ScannerScannerscnewScanner(System.in);intnum-1;while(num!0){numsc.nextInt();System.out.println(你输入了num);}三、do-while 循环do{// 循环体}while(条件);先执行一次再判断。无论条件真假循环体至少执行一次。inti10;do{System.out.println(至少执行一次i);i;}while(i5);// 输出一次至少执行一次10典型应用菜单系统——先显示菜单用户选择后再判断是否继续。// 菜单系统至少显示一次菜单选 0 退出需 import java.util.ScannerScannerscnewScanner(System.in);intchoice;do{System.out.println(1. 查询余额 2. 转账 0. 退出);choicesc.nextInt();if(choice1){System.out.println(余额100 元);}}while(choice!0);System.out.println(已退出系统);四、三种循环对比特性forwhiledo-while判断时机先判断先判断后判断最少执行次数0 次0 次1 次适用场景次数确定次数不确定至少执行一次三者可以互相转换选最贴合场景的即可次数确定用 for次数不确定用 while必须先跑一次用 do-while。另外说明一下循环语句在 JDK 8、JDK 11、JDK 17 三个版本里的写法完全一致本节讲的内容三个版本通用老项目和新项目写起来都一样。五、break 与 continuebreak立即终止整个循环for(inti1;i10;i){if(i5){break;// 循环到此为止}System.out.print(i );// 输出1 2 3 4}continue跳过本次循环继续下一次for(inti1;i10;i){if(i%20){continue;// 偶数跳过不打印}System.out.print(i );// 输出1 3 5 7 9}嵌套循环中的标签 break了解outer:for(inti0;i3;i){for(intj0;j3;j){if(j1){breakouter;// 直接跳出外层循环}System.out.println(i,j);}}// 只输出 0,0实际开发中标签 break 很少用能用方法封装就尽量不用。六、循环经典练习1. 计算 1 到 100 的和intsum0;for(inti1;i100;i){sumi;}System.out.println(12...100 sum);// 50502. 打印九九乘法表for(inti1;i9;i){for(intj1;ji;j){System.out.print(j*i(i*j)\t);}System.out.println();// 换行}3. 判断质数intnum97;booleanisPrimetrue;for(inti2;iMath.sqrt(num);i){if(num%i0){isPrimefalse;break;// 已确定不是质数提前结束}}System.out.println(num(isPrime? 是质数: 不是质数));七、死循环与规避// 经典死循环while(true){// 配合 break 使用}for (;;)和do { } while (true)也是死循环写法。死循环常用于事件监听、服务器等待请求等场景必须保证内部有跳出条件。普通循环写死循环如忘记i是常见 bug。八、扩展知识1. break / continue / return 的区别break结束整个循环或 switchcontinue跳过本次迭代直接进入下一次return结束整个方法回到调用处// return直接结束整个方法方法里后面的代码都不执行staticvoiddemoReturn(){for(inti1;i10;i){if(i3){return;// 方法到此结束}System.out.print(i );}System.out.println(这行不会执行);}demoReturn();// 输出1 22. 标签循环标签加在循环语句前outer:用于从内层循环直接跳出或跳过外层循环break 和 continue 都可以配合使用// 找二维数组里第一个等于 0 的位置找到就整体退出int[][]grid{{1,2},{3,0},{4,5}};found:for(inti0;igrid.length;i){for(intj0;jgrid[i].length;j){if(grid[i][j]0){System.out.println(找到 0i,j);// 找到 01,1breakfound;}}}3. for-each 的底层for-each 是 for 的语法糖遍历数组或集合时不用写下标int[]nums{1,2,3};for(intn:nums){System.out.print(n );// 1 2 3}数组的 for-each 底层就是下标循环集合的 for-each 底层是迭代器 Iterator两者在 JDK 8/11/17 中写法一致。注意for-each 拿到的是元素的副本直接修改元素无效详见易错点。九、易错点1. 忘记更新循环变量死循环// ❌ 忘了 i条件永远成立死循环inti0;while(i5){System.out.println(i);// 没有 i}// ✅ 循环体内更新循环变量intj0;while(j5){System.out.println(j);j;}2. 边界 off-by-one多一次或少一次// ❌ 想打印 1~5条件写错多了一次for(inti1;i51;i){System.out.println(i);// 1 2 3 4 5 6}// ✅ 先想清楚区间打印 1~5 用 i 5打印 0~4 用 i 5for(inti1;i5;i){System.out.println(i);}3. for 循环里 i 与 i 混用// ❌ 步进写两处循环次数和预期不符for(inti0;i5;i2){i;// 每轮实际加 3}// 循环两次i 依次为 1、4// ✅ 步进只写在 for 的第三部分循环体里不要再动 ifor(inti1;i5;i){System.out.println(i);}4. for-each 里修改元素无效// ❌ 想把每个元素翻倍数组其实没变需 import java.util.Arraysint[]arr{1,2,3};for(intn:arr){nn*2;// 改的是副本 n不是数组元素}System.out.println(Arrays.toString(arr));// [1, 2, 3]没变// ✅ 要改元素用带下标的普通 forfor(inti0;iarr.length;i){arr[i]arr[i]*2;}System.out.println(Arrays.toString(arr));// [2, 4, 6]5. 循环里拼接字符串性能差// ❌ 每轮都生成新字符串对象循环多了非常慢Strings;for(inti1;i10000;i){ssi;// 每轮都 new 一个新 String}// ✅ 用 StringBuilder 收集最后一次性转成 StringStringBuildersbnewStringBuilder();for(inti1;i10000;i){sb.append(i);}Stringresultsb.toString();十、小结for 适合次数确定while 适合次数不确定do-while 至少执行一次break 结束整个循环continue 跳过本次return 结束整个方法循环变量要更新避免死循环边界还是先想清楚for-each 简洁但改不了元素大量拼接字符串用 StringBuilder嵌套循环注意内外层变量的命名区分本系列三个 LTS 版本 JDK 8/11/17 中循环写法完全一致下一节学习数组。下一篇第7章 数组