java餐厅订餐系统需用arraylist+面向对象建模:food(id/name/price/stock)、orderitem(food引用/quantity)、order(arraylist/status/id)、restaurantsystem(协调数据与业务);库存校验须前置且原子,控制台交互须处理输入异常与空指针。

Java 里搭一个“简单”的餐厅订餐系统,不等于写个控制台菜单就完事——真要能跑、能增删改查、有基本业务逻辑(比如菜品库存扣减、订单状态流转),至少得用上 ArrayList 做内存数据容器 + 面向对象建模 + 控制台交互循环。Spring Boot 或数据库属于进阶需求,初始阶段强行加反而掩盖核心设计问题。
怎么组织核心类:别一上来就写 Main
先想清楚谁在系统里“干活”:顾客、菜品、订单、订单项。每个对应一个类,职责分明:
-
Food类存id、name、price、stock—— 库存必须是 int,别用 double,避免浮点误差影响扣减 -
OrderItem存food引用、quantity,别存 foodId 再去查,内存模型里直接持有对象更直观 -
Order用ArrayList<orderitem></orderitem>装多项,自动生成id(用 static 计数器),记录status("pending"/"confirmed"/"cancelled" 字符串即可) -
RestaurantSystem作为协调者,持有一个ArrayList<food></food>和一个ArrayList<order></order>,所有业务方法(如placeOrder()、cancelOrder())都定义在这里
下单时怎么安全扣库存:检查和更新必须原子
用户点 3 份宫保鸡丁,但库存只剩 2,不能下成功再抛异常——得在创建 OrderItem 前就校验。常见错误是先 new 再扣,导致校验和扣减之间存在时间差(虽然内存单线程不明显,但逻辑已坏):
- 在
placeOrder()内部,遍历每个OrderItem,调用food.getStock() >= item.getQuantity()逐个检查 - 全部通过后,再统一执行
food.decreaseStock(item.getQuantity()) - 任一失败,整个订单不创建,直接返回提示,不修改任何状态
- 别在
Food类里写buy(int n)这种带副作用的方法——它不该知道自己被谁买,只提供decreaseStock()和increaseStock()这样的中性操作
控制台交互怎么避免陷入死循环或空指针
用 Scanner 读输入时,最容易崩在没处理换行符残留、没校验数字格式、没捕获 InputMismatchException:
立即学习“Java免费学习笔记(深入)”;
- 每次调用
scanner.nextInt()后,紧跟scanner.nextLine()消掉回车,否则下一次nextLine()会立刻返回空字符串 - 所有用户输入的 ID 类型字段(如菜品 ID、订单 ID),统一用
scanner.hasNextInt()预检,不满足就scanner.next()吃掉非法输入并提示重输 - 查找对象时(如根据 ID 查
Food),一定要判空:if (food == null) { System.out.println("未找到菜品 ID: " + id); continue; },别假设用户一定输对 - 菜单选项用 switch 匹配
int,别用字符串比较,减少拼写错误风险
真正卡住人的地方往往不是语法,而是“订单确认后能不能再修改菜品数量”“取消订单要不要恢复库存”这类业务规则没想清楚就编码。先用纸笔把几个关键流程(下单 → 确认 → 取消)的状态变化画出来,比急着敲 public class 有用得多。










