You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Java 8中基于商品类别和总数量计算折扣?

问题修正:按类别总数量计算折扣的购物车总价方法

数据集

name: tea, pricePerUnit: 5.3, quantity: 2, category: drinks
name: coffee, pricePerUnit: 3.5, quantity: 2, category: drinks
name: cheese, pricePerUnit: 8, quantity: 2, category: food

折扣规则

同一类别下商品总购买数量超过3件,该类别下所有商品均享受10%折扣。

存在Bug的原代码

public BigDecimal calculateTotalWithDiscountAndCategory(ShoppingCart shoppingCart){

        return  shoppingCart.getProducts()
                .stream()
                .collect(Collectors.groupingBy(Product::getCategory))
                .entrySet()
                .stream()
                .map( v -> v.getValue()
                        .stream()
                        .map(product ->{
                            if(product.getQuantity() > 3){
                                BigDecimal currentTotal = product.getPricePerUnit().multiply(BigDecimal.valueOf(product.getQuantity()));
                                return currentTotal.multiply(BigDecimal.valueOf(0.9));

                            }else {
                                return product.getPricePerUnit().multiply(BigDecimal.valueOf(product.getQuantity()));
                            }
                                }
                        )
                        .reduce(BigDecimal::add)
                        .orElse(BigDecimal.ZERO)

                ).reduce(BigDecimal::add)
                .orElse(BigDecimal.ZERO);

    }

Bug分析

原代码错误地判断单个商品的购买数量是否超过3,但规则要求的是整个类别下的总数量超过3才给该类别所有商品打折扣。比如示例中drinks类别总数量是4,符合折扣条件,但原代码因为单个商品数量都是2,所以没触发折扣。

修改后的代码

public BigDecimal calculateTotalWithDiscountAndCategory(ShoppingCart shoppingCart) {
    return shoppingCart.getProducts()
            .stream()
            .collect(Collectors.groupingBy(Product::getCategory))
            .entrySet()
            .stream()
            .map(entry -> {
                // 计算当前类别下的总购买数量
                int totalCategoryQuantity = entry.getValue()
                        .stream()
                        .mapToInt(Product::getQuantity)
                        .sum();
                // 判断是否满足折扣条件
                boolean needDiscount = totalCategoryQuantity > 3;
                
                // 计算该类别下所有商品的总价,按需应用折扣
                return entry.getValue()
                        .stream()
                        .map(product -> {
                            BigDecimal itemTotal = product.getPricePerUnit()
                                    .multiply(BigDecimal.valueOf(product.getQuantity()));
                            return needDiscount ? itemTotal.multiply(BigDecimal.valueOf(0.9)) : itemTotal;
                        })
                        .reduce(BigDecimal::add)
                        .orElse(BigDecimal.ZERO);
            })
            .reduce(BigDecimal::add)
            .orElse(BigDecimal.ZERO);
}

修改说明

  1. 先统计每个类别下的总购买数量,而非单个商品的数量
  2. 根据类别总数量判断是否触发折扣规则
  3. 若满足折扣条件,该类别下所有商品的总价统一乘以0.9,否则按原价计算
  4. 最后汇总所有类别的计算结果得到最终总价

内容的提问来源于stack exchange,提问作者D.Anush

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 04:54:23