Java实现月度销售折扣跟踪及P1商品交易特殊逻辑方案咨询
方案可行性判断
你提到的HashMap方案完全可行,完全可以覆盖你当前的所有需求:
- 以年月作为key的逻辑合理:既可以用
Integer存储202102、202103这类拼接的数字,也可以直接用Java 8+提供的java.time.YearMonth类作为key,语义更清晰,不需要手动处理字符串/数字拼接,还能避免格式化错误 - 自定义存储对象可以直接封装三类你需要的维度数据:当月总销售额、当月总折扣额、当月P1商品的交易计数(如果执行自定义逻辑需要用到交易详情,也可以加一个List存储P1交易的明细)
更优实现建议
如果你使用Java 8及以上版本,可以参考下面的优化方案,代码更简洁也更不容易出错:
- 首先定义月份统计实体类,封装属性操作避免直接暴露字段修改
import java.math.BigDecimal; public class MonthlyStat { // 用BigDecimal避免金额计算的浮点精度问题,如果作业要求不高也可以直接用int存储 private BigDecimal totalSale = BigDecimal.ZERO; private BigDecimal totalDiscount = BigDecimal.ZERO; private int p1TradeCount = 0; // 累加销售额 public void addSale(BigDecimal saleAmount) { this.totalSale = this.totalSale.add(saleAmount); } // 累加折扣额 public void addDiscount(BigDecimal discountAmount) { this.totalDiscount = this.totalDiscount.add(discountAmount); } // P1交易计数+1,返回当前计数 public int incrementP1Count() { return ++this.p1TradeCount; } // 按需添加getter方法即可 }
- 遍历原始数据的处理逻辑示例
// 原始数据对应的实体类为SaleRecord,存储你读取到的每一行销售数据 Map<YearMonth, MonthlyStat> statMap = new HashMap<>(); for (SaleRecord record : originDataList) { // 解析交易日期对应的年月 LocalDate tradeDate = record.getTradeDate(); YearMonth yearMonth = YearMonth.from(tradeDate); // 如果对应月份没有统计对象则自动新建 MonthlyStat monthlyStat = statMap.computeIfAbsent(yearMonth, k -> new MonthlyStat()); // 累加当月销售额、折扣额 monthlyStat.addSale(record.getSale()); monthlyStat.addDiscount(record.getDiscount()); // 处理P1商品逻辑 if ("P1".equals(record.getProduct())) { int currentCount = monthlyStat.incrementP1Count(); // 匹配到当月第3笔P1交易,执行自定义逻辑 if (currentCount == 3) { runYourCustomLogic(record); } } }
- 如果你的需求只是一次性统计、不需要保留中间状态,也可以用Stream流的
groupingBy+teeing(Java 12及以上支持)直接完成最终的销售额、折扣额统计,但这种方式处理第三笔P1交易的触发逻辑会更麻烦,更适合只需要最终统计结果的场景。
内容的提问来源于stack exchange,提问作者Kashyap
相关产品推荐
相关产品推荐

