购物车类核心字段包括userId(可为空)、sessionId、items(推荐Map或含productId/quantity/priceAtAddTime/skuId的CartItem);多线程下应使用ConcurrentHashMap+compute/merge或数据库行级锁;add()返回boolean以明确标识库存不足等业务失败场景。

购物车类该包含哪些核心字段
一个可用的购物车对象不能只存商品列表,必须区分「当前会话购物车」和「用户持久化购物车」。实际开发中,Cart 类至少要包含:userId(可为空,用于未登录场景)、sessionId(临时标识)、items(Map 或 List)。用 Map 存 productId → quantity 更易查重和更新,但丢失商品元数据;用 CartItem 自定义类则需确保 equals/hashCode 基于 productId 实现,否则 remove() 会失效。
CartItem 对象为什么不能直接用 ArrayList
直接存 Product 对象会导致两个问题:一是数量无法独立维护(同一商品多次添加变成多条记录),二是库存变更或价格调整后,购物车里的 Product 信息已过期。正确做法是让 CartItem 持有 productId、quantity、priceAtAddTime(快照价)、skuId(如颜色尺码)等字段。这样结账时能比对当前库存与快照价,避免“下单成功但缺货”或“价格跳变”问题。
如何安全地在多线程下更新购物车
Web 应用中用户可能同时在多个标签页操作购物车,add()、updateQuantity()、remove() 都不是原子操作。别用 synchronized(this)——它只对单实例有效,而 Spring 中 CartService 默认是 singleton,但每个用户应有独立购物车数据。推荐方案:
• 用 ConcurrentHashMap 存储用户级购物车缓存(key 是 userId 或 sessionId)
• 更新具体商品数量时,用 compute() 或 merge() 方法,比如:cartItems.merge(productId, 1, Integer::sum)
• 若涉及数据库持久化,必须加行级锁(如 SELECT ... FOR UPDATE)或用乐观锁(version 字段)
为什么 add() 方法要返回布尔值而不是 void
返回 boolean 是为了暴露业务语义:添加成功?库存不足被拒绝?商品已下架?前端需要据此给出不同提示。例如:if (!cart.add(productId, 2)) { throw new OutOfStockException(); }。如果写成 void,异常只能靠 try-catch 捕获,但像“库存刚好剩 1 却想加 2 件”这种部分失败场景,很难区分是校验失败还是系统错误。另外,测试时也更容易断言行为:assertTrue(cart.add(1001L, 1));
立即学习“Java免费学习笔记(深入)”;
真正难的不是建几个类,而是决定「什么时候读库存」「什么时候锁库存」「快照价要不要参与满减计算」——这些逻辑一旦散落在各个 add/remove 方法里,后续改促销规则就会踩坑。










