使用Stream API遍历List并对比Map生成结果Map遇问题求助
问题解决方案
场景说明
定义了如下实体类:
public class ProductInStockRequest { private String productId; private Integer requestedQuantity; // 必须补充构造方法与getter,否则无法实例化和读取属性 public ProductInStockRequest(String productId, Integer requestedQuantity) { this.productId = productId; this.requestedQuantity = requestedQuantity; } public String getProductId() { return productId; } public Integer getRequestedQuantity() { return requestedQuantity; } }
现有以下数据集合:
- 请求列表:
List<ProductInStockRequest> requestList = new ArrayList<>(); requestList.add(new ProductInStockRequest("100", 5)); requestList.add(new ProductInStockRequest("200", 11)); requestList.add(new ProductInStockRequest("300", 33)); requestList.add(new ProductInStockRequest("400", 55));
- 库存映射:
Map<String, Integer> productInDbMap = new HashMap<>(); productInDbMap.put("100", 10); productInDbMap.put("200", 10); productInDbMap.put("300", 44); productInDbMap.put("400", 77);
需求:遍历请求列表,检查每个商品库存是否满足请求数量,将结果存入Map<String, String> responseMap(key为商品ID,value为order-able表示库存充足,否则表示缺口数量)。
原代码问题分析
原代码使用Stream的map操作,但Stream是惰性求值逻辑,没有终端操作的话,中间操作不会执行,导致遍历逻辑完全没运行。此外,直接在Stream中修改外部集合不符合函数式编程设计理念,还可能引发线程安全问题。同时原代码中缺口数量的计算逻辑写反了,会得到负数结果。
解决方案
方案1:修复原逻辑(添加终端操作)
如果要保留原有遍历思路,用forEach替代map(无需转换元素,仅执行遍历逻辑),并添加终端操作:
Map<String, String> responseMap = new HashMap<>(); requestList.stream().forEach(requestedItem -> { Integer stock = productInDbMap.get(requestedItem.getProductId()); // 处理库存不存在的情况,避免空指针异常 if (stock == null) { responseMap.put(requestedItem.getProductId(), "out of stock"); return; } int requestedQty = requestedItem.getRequestedQuantity(); if (stock >= requestedQty) { responseMap.put(requestedItem.getProductId(), "order-able"); } else { // 修正缺口计算逻辑:请求量 - 库存 int shortage = requestedQty - stock; responseMap.put(requestedItem.getProductId(), String.valueOf(shortage)); } });
方案2:符合Stream规范的写法(直接生成结果Map)
使用Collectors.toMap直接生成目标Map,避免修改外部集合,更贴合函数式编程风格:
Map<String, String> responseMap = requestList.stream() .collect(Collectors.toMap( ProductInStockRequest::getProductId, requestedItem -> { Integer stock = productInDbMap.get(requestedItem.getProductId()); if (stock == null) { return "out of stock"; } int requestedQty = requestedItem.getRequestedQuantity(); return stock >= requestedQty ? "order-able" : String.valueOf(requestedQty - stock); } ));
额外注意事项
ProductInStockRequest必须补充构造方法和getter,否则无法实例化对象或读取属性,编译会报错。- 必须处理
productInDbMap中无对应商品ID的情况,避免空指针异常。 - 缺口数量应为请求量减去库存,原代码逻辑写反会得到负数,不符合业务预期。
内容的提问来源于stack exchange,提问作者Kirill Sazonov
相关产品推荐
相关产品推荐

