Java实习生求助:如何用BigDecimal类型Map扣减BigDecimal变量值
解决BigDecimal类型Map值扣减仓库可用量的问题
核心逻辑说明
因为BigDecimal是不可变类,所有运算操作都会返回新的BigDecimal对象,无法直接修改原对象的值。所以扣减仓库可用量的核心是:遍历订单所需的原料条目,取出仓库中对应原料的当前值,执行扣减运算后,将新值重新存入仓库Map。
场景代码实现
假设核心类定义如下(简化版):
// 产品类型枚举 enum ProductType { FLOUR, CHEESE, TOMATO_SAUCE, PEPPERONI } // 订单原料数量类(数值为BigDecimal类型) class Quantity { private BigDecimal amount; public Quantity(BigDecimal amount) { this.amount = amount; } public BigDecimal getAmount() { return amount; } }
以下是扣减仓库可用量的核心方法:
import java.math.BigDecimal; import java.math.RoundingMode; import java.util.Map; public class WarehouseService { // 仓库存储:键为原料类型,值为当前可用量(BigDecimal) private Map<ProductType, BigDecimal> warehouse; public WarehouseService(Map<ProductType, BigDecimal> warehouse) { this.warehouse = warehouse; } /** * 根据披萨订单的原料需求,扣减仓库对应原料的可用量 * @param pizzaIngredients 披萨所需的原料及对应数量 * @throws IllegalArgumentException 原料不存在或库存不足时抛出异常 */ public void deductIngredients(Map<ProductType, Quantity> pizzaIngredients) { for (Map.Entry<ProductType, Quantity> entry : pizzaIngredients.entrySet()) { ProductType ingredientType = entry.getKey(); BigDecimal requiredAmount = entry.getValue().getAmount(); // 检查仓库中是否存在该原料 BigDecimal currentStock = warehouse.get(ingredientType); if (currentStock == null) { throw new IllegalArgumentException("仓库无此原料:" + ingredientType); } // 检查原料库存是否充足(BigDecimal比较必须用compareTo,不能用equals) if (currentStock.compareTo(requiredAmount) < 0) { throw new IllegalArgumentException("原料" + ingredientType + "库存不足,当前:" + currentStock + ",需:" + requiredAmount); } // 执行扣减,按业务需求设置精度与舍入模式(示例保留2位小数,四舍五入) BigDecimal newStock = currentStock.subtract(requiredAmount).setScale(2, RoundingMode.HALF_UP); // 将扣减后的新库存放回仓库 warehouse.put(ingredientType, newStock); } } }
关键注意事项
- 不可变性处理:必须用
subtract()返回的新BigDecimal对象替换仓库中原有的值,直接修改原对象无效 - 数值比较:BigDecimal的大小比较要用
compareTo()方法,equals()会同时比较值和精度,易导致判断错误 - 异常与空值处理:根据业务需求选择抛出异常、返回错误提示或降级处理,避免空指针或库存负数
- 精度控制:通过
setScale()指定小数位数和舍入模式,防止计算精度丢失或出现不符合业务要求的数值 - 并发安全:多线程环境下建议使用
ConcurrentHashMap作为仓库容器,或给方法加同步锁,避免并发修改导致数据不一致
内容的提问来源于stack exchange,提问作者Veselin Zahariev
相关产品推荐
相关产品推荐

