「Java流程控制」while循环

113 阅读8分钟

Java里的while循环就像每天早晨的闹钟,只要条件满足就会一直响个不停,直到把它关掉为止。

while循环就像重复做同一件事

想象一下在玩投篮游戏,只要篮筐里还有位置,就要一直往里投球。用while循环写出来是这样的:

int 篮筐容量 = 5;
int 投球次数 = 0;

while (投球次数 < 篮筐容量) {
    System.out.println("第" + (投球次数 + 1) + "个球投进啦!");
    投球次数++;
}
System.out.println("篮筐满啦,不能再投了!");

代码解析

  • while后面的括号里是条件,就是判断篮筐还有没有空位。
  • 大括号里的代码块就是要重复执行的动作。
  • 投球次数++这个很重要,每次循环都让计数器加1,不然就会变成无限循环。
  • 当条件不满足时,循环就结束,执行后面的语句。

案例解析

猜数字游戏

编写一个程序,实现经典的小游戏,让电脑随机出一个1 ~ 100的整数,来猜这个数字。

# 源文件保存为“GuessNumber.java”。
import java.util.Random;
import java.util.Scanner;

public class GuessNumber {
    public static void main(String[] args) {
        Random rand = new Random();
        int number = rand.nextInt(100) + 1; // 1-100的随机数
        Scanner scanner = new Scanner(System.in);
        int count = 0;
        boolean right = false;

        System.out.println("我想了个1-100的数字,猜猜看?");

        while (!right) {
            System.out.print("你的猜测:");
            int guessNumber = scanner.nextInt();
            count++;

            if (guessNumber > number) {
                System.out.println("太大啦!");
            } else if (guessNumber < number) {
                System.out.println("太小啦!");
            } else {
                right = true;
                System.out.println("恭喜!你用了" + count + "次猜对了!");
            }
        }
        scanner.close();
    }
}

运行结果 依次输入猜测的数字,会得到:

我想了个1-100的数字,猜猜看? 你的猜测:50 太大啦! 你的猜测:25 太大啦! 你的猜测:13 太大啦! 你的猜测:5 太小啦! 你的猜测:9 太小啦! 你的猜测:11 恭喜!你用了6次猜对了!

这个游戏中,while (!right)是循环条件,只要没猜对就一直循环。每次循环都让玩家输入一个数字,然后给出提示。

智能电饭煲煮饭程序

想象一下电饭煲煮饭,它会一直煮饭直到水分收干。用while循环模拟这个过程特别形象:

# 源文件保存为“RiceCooker.java”。
public class RiceCooker {
    public static void main(String[] args) {
        double water = 100; // 单位:毫升
        int time = 0; // 单位:分钟

        System.out.println("开始煮饭...");

        while (water > 0) {
            water -= 8.5; // 每分钟蒸发8.5ml
            time++;

            System.out.println("第" + time + "分钟,剩余水量:"
                    + (water > 0 ? water : 0) + "ml");
        }

        System.out.println("饭煮好啦!总共用时:" + time + "分钟");
    }
}

运行结果

开始煮饭... 第1分钟,剩余水量:91.5ml 第2分钟,剩余水量:83.0ml 第3分钟,剩余水量:74.5ml 第4分钟,剩余水量:66.0ml 第5分钟,剩余水量:57.5ml 第6分钟,剩余水量:49.0ml 第7分钟,剩余水量:40.5ml 第8分钟,剩余水量:32.0ml 第9分钟,剩余水量:23.5ml 第10分钟,剩余水量:15.0ml 第11分钟,剩余水量:6.5ml 第12分钟,剩余水量:0.0ml 饭煮好啦!总共用时:12分钟

这个程序里,while循环就像电饭煲的加热元件,只要还有水就继续工作。每次循环水量减少8.5ml。

超市收银扫描商品

超市收银员扫码商品时,只要还有商品就继续扫,用while模拟写出这过程。

# 源文件保存为“CashRegister.java”。
import java.util.Scanner;

public class CashRegister {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        double total = 0;
        int count = 0;

        System.out.println("=== 收银系统 ===");
        System.out.println("请输入商品价格(输入0结束):");

        while (true) {
            System.out.print("商品" + (count + 1) + ":");
            double price = scanner.nextDouble();

            if (price == 0) {
                break; // 输入0时退出循环
            }

            total += price;
            count++;
        }

        System.out.println("共" + count + "件商品,总计:" + total + "元");
        scanner.close();
    }
}

运行结果 依次输入商品的价格:

=== 收银系统 === 请输入商品价格(输入0结束): 商品1:20 商品2:10 商品3:30 商品4:0 共3件商品,总计:60.0元

这个例子用了while(true)创建无限循环,然后用break在特定条件下退出。就像收银员不知道顾客有多少商品,只能一直扫直到顾客说"没有了"。

常见错误

错误:忘记更新循环变量

int i = 0;
while (i < 10) {
    System.out.println("卡在这儿了");
    // 忘了写 i++,结果无限循环
}

解决方法:检查循环体内有没有改变循环条件的语句

错误:错把赋值当比较

int x = 5;
while (x = 10) { // 应该是x == 10
    System.out.println("又错了");
}

解决方法:比较要用==,不是=

错误:循环条件永远为真

while (true) { // 没有退出条件
    System.out.println("停不下来");
}

解决方法:确保循环有结束条件,或者用break退出

修改错误代码:下面是一段统计成绩的程序,结果结果存在问题,现在来看看问题出在哪里,如何改正。

// 错误示范
int passNumber = 0;
int totalNumber = 10;
while (totalNumber >= 0) { 
    System.out.println("输入第" + (totalNumber) + "个学生成绩:");
    double score = new Scanner(System.in).nextDouble();
    if (score >= 60) {
        passNumber++;
    }
    totalNumber--;  // 循环变量写在最后容易忘
}
System.out.println("passNumber:" + passNumber);

主要问题:循环条件应该是totalNumber > 0,否则会多循环一次。改进后:

// 正确写法
int passNumber = 0;
int totalNumber = 10;
while (totalNumber > 0) {  // 这里应该是>0
    System.out.println("输入第" + (totalNumber) + "个学生成绩:");
    double score = new Scanner(System.in).nextDouble();
    if (score >= 60) {
        passNumber++;
    }
    totalNumber--;  // 循环变量写在最后容易忘
}
System.out.println("passNumber:" + passNumber);

练习题

理论题

下面代码会输出什么?

int i = 3;
while (i > 0) {
    System.out.println(i);
    i--;
}

答案:输出3、2、1。每次循环i减1,直到i不大于0为止。

下面代码会输出什么?为什么?

int x = 5;
while (x-- > 0) {
   System.out.print(x + " ");
}

答案:输出"4 3 2 1 0 "。因为x--是先比较后自减,第一次比较时x是5,循环体内x变成4,依此类推。

如何修复这个无限循环?

int count = 1;
while (count <= 5) {
    System.out.println(count);
}

解析:缺少count++,循环变量没有变化导致无限循环。

如何优化这个循环?

int i = 0;
while (i < 100) {
   System.out.println(i);
   i += 2;
}

解析:虽然这段代码没问题,但用for循环更合适:

for (int i = 0; i < 100; i += 2) {
   System.out.println(i);
}

实践题

倒计时程序:写个从10倒数到1然后发射的程序。

# 源文件保存为“CountDown.java”。
public class CountDown {
    public static void main(String[] args) {
        int second = 10;

        while (second >= 1) {
            System.out.println(second + "...");
            second--;
        }
        System.out.println("发射!");
    }
}

运行结果

10... 9... 8... 7... 6... 5... 4... 3... 2... 1... 发射!

银行存款计算:计算多少年后存款能翻倍。

# 源文件保存为“DepositCalculation.java”。
public class DepositCalculation {
    public static void main(String[] args) {
        double principal = 10000;
        double rate = 0.05; // 5%
        int year = 0;

        while (principal < 20000) {
            principal *= (1 + rate);
            year++;
            System.out.println("第" + year + "年,余额:" + principal);
        }
        System.out.println("需要" + year + "年翻倍");
    }
}

运行结果

第1年,余额:10500.0 第2年,余额:11025.0 第3年,余额:11576.25 第4年,余额:12155.0625 第5年,余额:12762.815625000001 第6年,余额:13400.956406250001 第7年,余额:14071.004226562502 第8年,余额:14774.554437890627 第9年,余额:15513.28215978516 第10年,余额:16288.946267774418 第11年,余额:17103.393581163138 第12年,余额:17958.563260221297 第13年,余额:18856.491423232364 第14年,余额:19799.315994393983 第15年,余额:20789.281794113682 需要15年翻倍

关键点:循环条件是本金小于目标金额,每年本金增加5%。

密码验证:给用户3次输入密码的机会。

# 源文件保存为“CheckPasswd.java”。
import java.util.Scanner;

public class CheckPasswd {
    public static void main(String[] args) {
        String password = "java123";
        int count = 3;
        boolean pass = false;
        Scanner scanner = new Scanner(System.in);

        while (count > 0 && !pass) {
            System.out.print("请输入密码(还剩" + count + "次机会):");
            String input = scanner.nextLine();

            if (input.equals(password)) {
                pass = true;
            } else {
                count--;
            }
        }

        if (pass) {
            System.out.println("登录成功!");
        } else {
            System.out.println("账户已锁定!");
        }
        scanner.close();
    }
}

运行结果 输入密码进行验证:

请输入密码(还剩3次机会):123456 请输入密码(还剩2次机会):java123 登录成功!

技巧:用&&组合两个条件,只要有一个不满足就退出循环。

自动售货机库存管理:编写一个模拟售货机出货的程序,库存不足时停止。

# 源文件保存为“Automat.java”。
import java.util.Scanner;

public class Automat {
    public static void main(String[] args) {
        int stock = 10;
        Scanner scanner = new Scanner(System.in);

        System.out.println("当前库存:" + stock);

        while (stock > 0) {
            System.out.print("请输入购买数量(输入0退出):");
            int buy = scanner.nextInt();

            if (buy == 0) {
                break;
            } else if (buy > stock) {
                System.out.println("库存不足,剩余:" + stock);
            } else {
                stock -= buy;
                System.out.println("出货" + buy + "个,剩余:" + stock);
            }
        }

        System.out.println("已售罄!");
        scanner.close();
    }
}

运行结果 依次输入购买数量:

当前库存:10 请输入购买数量(输入0退出):5 出货5个,剩余:5 请输入购买数量(输入0退出):4 出货4个,剩余:1 请输入购买数量(输入0退出):2 库存不足,剩余:1 请输入购买数量(输入0退出):1 出货1个,剩余:0 已售罄!

关键点:循环内嵌套if-else处理三种情况:退出、库存不足、正常购买。库存减到0时自动结束循环。

猜拳游戏连胜记录:统计玩家连续赢了多少局,直到输为止

# 源文件保存为“WinNumber.java”。
import java.util.Random;
import java.util.Scanner;

public class WinNumber {
    public static void main(String[] args) {
        Random rand = new Random();
        Scanner scanner = new Scanner(System.in);
        int 连胜 = 0;
        
        while (true) {
            System.out.print("请输入(1石头 2剪刀 3布):");
            int 玩家 = scanner.nextInt();
            int 电脑 = rand.nextInt(3) + 1;
            
            // 判断胜负
            if (玩家 == 电脑) {
                System.out.println("平局!");
            } else if ((玩家==1 && 电脑==2) || 
                      (玩家==2 && 电脑==3) || 
                      (玩家==3 && 电脑==1)) {
                连胜++;
                System.out.println("赢了!当前连胜:" + 连胜);
            } else {
                System.out.println("输了!最终连胜:" + 连胜);
                break;
            }
        }
        scanner.close();
    }
}

运行结果 依次输入

请输入(1石头 2剪刀 3布):1 平局! 请输入(1石头 2剪刀 3布):1 输了!最终连胜:0

技巧:用while(true)创建无限循环,只有输的时候才break退出。胜负判断用逻辑运算符组合三种赢的情况。

电梯模拟程序:模拟电梯从1楼运行到目标楼层的过程

# 源文件保存为“ElevatorSimulation.java”。
import java.util.Scanner;

public class ElevatorSimulation {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入目标楼层:");
        int target = scanner.nextInt();
        int current = 1;

        System.out.println("电梯从1楼出发...");

        while (current < target) {
            current++;
            System.out.println("到达" + current + "楼");

        }

        System.out.println("已到达目标楼层" + target + "楼");
        scanner.close();
    }
}

运行结果 输入5,会得到:

请输入目标楼层:5 电梯从1楼出发... 到达2楼 到达3楼 到达4楼 到达5楼 已到达目标楼层5楼

工程思维:用current < target作为循环条件,确保不会过冲。Thread.sleep模拟电梯运行时间,增强真实感。