Java实现Cyride公交系统时站点计算错误与乘客数统计异常求助
CyrideBus 类问题排查与修复方案
问题原因梳理
1. 站点计算不符合预期
- 核心原因:实例化对象时参数传参顺序错误。类构造方法第一个参数是最大载客量
givenMaxCapacity,第二个参数才是站点数givenNumStops。如果创建3个站点的实例时错误写成new CyrideBus(3, 100),会把站点数设为100,此时调用6次nextStop,currentStop = -1 + 6 = 5,5模100结果就是5,完全符合你遇到的错误表现。 - 验证:7个站点的实例调用137次
nextStop返回136,刚好是-1 + 137 = 136,说明站点数被设置为大于136的数值,完全匹配传参顺序错误的特征。 - 隐藏问题:原代码缺少参数合法性校验,如果站点数/最大载客量传值为0,会直接触发算术异常或逻辑错误。
2. 乘客数量统计错误
- 直接原因:
getTotalRiders方法实现逻辑完全错误,当前代码返回numPassengers + currentCapacity + 1,既不是当前乘客数也不是累计载客数,属于编码笔误。 - 缺失逻辑:如果需要统计累计总载客量,原代码没有对应的成员变量记录历史上车人数,仅靠
numPassengers只能统计当前车上的乘客数。 - 隐性问题:原代码缺少
numPassengers的显式初始化,虽然Java默认给int类型赋0,但显式初始化可读性更好。
修复方案
完整修改后代码
package hw1; public class CyrideBus { public static final int BUS_GARAGE = -1; // 新增累计载客量变量,统计所有成功上车的乘客总数 private int totalRidersCount; private int currentCapacity; private int numStops; private int numPassengers; private int currentStop; private boolean inService; // 修复原代码缺失的注释符号 // keeps track of bus stops public CyrideBus(int givenMaxCapacity, int givenNumStops) { // 新增参数合法性校验,避免非法传参导致逻辑错误 if (givenMaxCapacity <= 0) { throw new IllegalArgumentException("最大载客量必须大于0"); } if (givenNumStops <= 0) { throw new IllegalArgumentException("站点数必须大于0"); } currentCapacity = givenMaxCapacity; numStops = givenNumStops; currentStop = BUS_GARAGE; // 显式初始化乘客数 numPassengers = 0; totalRidersCount = 0; inService = true; } public int getCurrentCapacity() { return currentCapacity; } public int getCurrentStop() { return currentStop; } public int getNumPassengers() { return numPassengers; } // 修复总载客量统计逻辑 public int getTotalRiders() { return totalRidersCount; } public boolean isInService() { return inService; } public void nextStop (int peopleOff, int peopleOn) { currentStop = (currentStop + 1) % numStops; peopleOff = Math.max(0, peopleOff); peopleOn = Math.max(0, peopleOn); // 计算实际下车人数 numPassengers -= Math.min(peopleOff, numPassengers); // 计算可上车人数,避免超过最大载客量 int allowedOn = Math.min(peopleOn, currentCapacity - numPassengers); numPassengers += allowedOn; // 累计实际成功上车的人数到总载客量 totalRidersCount += allowedOn; } public void placeInService() { inService = true; } public void removeFromService() { inService = false; } }
使用注意事项
- 实例化对象时严格按照参数顺序传值:第一个参数填最大载客量,第二个参数填站点数,例如3个站点、最大载客50人的公交实例写法为
new CyrideBus(50, 3)。 - 获取当前车上乘客数调用
getNumPassengers()方法,获取线路累计总载客量调用getTotalRiders()方法。
验证效果
- 3个站点的实例,调用
nextStop6次:初始值-1,加6次1等于5,5模3等于2,符合预期结果。 - 7个站点的实例,调用
nextStop137次:-1+137=136,136模7等于3(7*19=133,136-133=3),符合预期结果。 - 乘客统计:当前乘客数不会超过最大载客量,累计载客量会准确统计所有成功上车的人数。
内容的提问来源于stack exchange,提问作者Jacob Tenold
相关产品推荐
相关产品推荐

