用scanner接收输入、arraylist存储cartitem实现购物车,需定义product和cartitem类,重写equals/hashcode以id为判等依据,用bigdecimal精确计算金额并规范输入校验。

怎么用 Scanner 和 ArrayList 搭出基础购物车结构
控制台购物车本质是数据暂存 + 交互循环,不需要数据库或 Web 框架。核心是用 ArrayList 存商品,用 Scanner 接收用户输入,再配合简单类封装商品和订单信息。
容易踩的坑:直接用 String 拼接商品信息(如 "iPhone,8999,2"),后续修改价格、数量会难维护;应该定义 Product 和 CartItem 类,把名称、价格、数量作为字段。
-
Product类只存商品原始信息(id、name、price) -
CartItem类额外持有quantity,避免重复创建相同商品对象 - 购物车本身用
ArrayList<cartitem></cartitem>,不是ArrayList<product></product> - 每次添加商品时,先遍历已有
CartItem,匹配product.id,存在则item.quantity++,不存在才新建
为什么 add() 和 remove() 要重写 equals() 和 hashCode()
当用户输入“删除 iPhone”或“清空购物车中所有耳机”,你得靠对象内容判断是否相等,而不是内存地址。如果没重写 equals(),cartItems.remove(item) 可能删不掉——因为新构造的 CartItem 和原列表里的不是同一个实例。
必须在 CartItem 类里基于 product.id(或 product.name,但 id 更稳妥)实现 equals() 和 hashCode():
立即学习“Java免费学习笔记(深入)”;
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CartItem cartItem = (CartItem) o;
return Objects.equals(product.getId(), cartItem.product.getId());
}漏掉这步,removeIf()、contains()、甚至用 Set 去重都会失效。
怎么处理用户输错、输空、输非数字这类输入异常
控制台程序最常崩在 scanner.nextInt() 遇到字母,或 scanner.nextLine() 被残留换行符跳过。不能靠 try-catch 包住整个循环,而要对每类输入做针对性清洗。
- 读整数前,先用
scanner.hasNextInt()判断,否则调nextInt()会抛InputMismatchException - 读完数字后,加一句
scanner.nextLine()吃掉换行符,否则下一次nextLine()会立刻返回空字符串 - 读商品名时,用
scanner.nextLine().trim(),避免用户多敲空格导致" iPhone "和"iPhone"匹配失败 - 菜单选项输入(如选 1-5),用
while (!scanner.hasNextInt() || scanner.nextInt() 5)不行——nextInt()被调两次。正确写法是先int choice = scanner.nextInt(),再判断范围
订单确认环节怎么避免“价格算错”这种低级失误
购物车显示总价 ≠ 订单最终金额。常见错误是直接对 CartItem 的 product.price * quantity 累加,但没考虑浮点精度(比如 19.99 × 2 = 39.979999...)。Java 里钱一律用 int(单位:分)或 BigDecimal。
推荐用 BigDecimal,但注意构造方式:
- ❌ 错误:
new BigDecimal(19.99)—— double 字面量本身就有精度损失 - ✅ 正确:
new BigDecimal("19.99")或BigDecimal.valueOf(1999).divide(BigDecimal.valueOf(100)) - 计算总价时,每个
CartItem的小计也用BigDecimal,别混用double中间变量 - 输出给用户看时,用
total.setScale(2, RoundingMode.HALF_UP).toString()格式化
这个细节一旦忽略,结账金额对不上,用户信任就没了——而它和业务逻辑无关,纯属类型使用错误。










