本文介绍如何利用 java stream api 高效判断一组订单是否能在当前库存下全部履约,核心是将库存转换为名称-数量映射表,再逐条校验订单需求是否不超过对应库存。
本文介绍如何利用 java stream api 高效判断一组订单是否能在当前库存下全部履约,核心是将库存转换为名称-数量映射表,再逐条校验订单需求是否不超过对应库存。
在电商、仓储或订单系统中,一个常见需求是:给定一份订单列表(List
由于 Order 和 Product 均按商品名(name)关联,最高效的方式是先将库存聚合为 Map
✅ 推荐方案:使用 Collectors.groupingBy 聚合库存(支持同名商品多条记录)
Map<string integer> stockMap = productList.stream()
.collect(Collectors.groupingBy(
Product::getName,
Collectors.summingInt(Product::getAmount)
));</string>
此方式能正确处理库存中存在多个同名商品(如两次入库 "apple")的场景,自动累加其 amount。
接着校验每笔订单:
boolean isFulfillable = orderList.stream()
.allMatch(order ->
stockMap.getOrDefault(order.getName(), 0) >= order.getAmount()
);
System.out.println("订单可全部履约: " + isFulfillable); // 输出: false(因 juice 需求3 > 库存2,milk 需求5 > 库存4)
? allMatch() 确保所有订单项均满足条件才返回 true;若只需检查是否存在不可履约项,可用 anyMatch() 配合取反逻辑。
⚠️ 简化方案(仅适用于商品名唯一场景)
若业务约束保证 productList 中每个 Product.name 唯一(即无重复商品条目),可改用更轻量的 toMap:
Map<string integer> stockMap = productList.stream()
.collect(Collectors.toMap(Product::getName, Product::getAmount));</string>
⚠️ 注意:此写法在遇到重复商品名时会抛出 IllegalStateException,生产环境建议显式处理冲突,例如:
.collect(Collectors.toMap(
Product::getName,
Product::getAmount,
Integer::sum // 合并函数:遇重复 key 时相加
))
? 完整可运行示例(整合进 TestWarehouse.main)
// ...(原有 Product/Order 类定义及实例化代码)
Map<string integer> stockMap = productList.stream()
.collect(Collectors.groupingBy(
Product::getName,
Collectors.summingInt(Product::getAmount)
));
boolean canFulfill = orderList.stream()
.allMatch(order -> stockMap.getOrDefault(order.getName(), 0) >= order.getAmount());
System.out.println("订单整体可履约: " + canFulfill); // false</string>
✅ 最佳实践总结
- 优先使用 groupingBy + summingInt:健壮性强,天然支持库存数据去重累加;
- 避免嵌套循环:勿对每个 Order 都 .stream().filter(...).findAny(),时间复杂度退化为 O(n×m);
- 空值防御:始终用 getOrDefault(key, 0) 替代 get(key),防止 NullPointerException;
- 语义明确:用 allMatch() 表达“全部满足”,比手动 forEach + 标志位更函数式、更安全。
通过合理组合 Stream 的聚合与匹配操作,一行声明式代码即可完成原本需多重遍历的库存校验逻辑,兼具可读性与性能优势。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











