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

如何用Java 8 Stream API重构多层嵌套循环的Map生成代码

Java 8 Stream重构多层循环提取SIM特征与OrderItem ID的Map实现

问题背景

需要将一段多层嵌套循环的代码用Java 8 Stream API重构,原代码功能是从IProductOrderDTO中提取名称为"SIM"的特征值作为Map的key,对应orderItem的ID作为Map的value。尝试编写的Stream代码无法同时获取这两个值,请求完善。

原循环代码

private Map<String,String> fetchAllSerialNumbers(IProductOrderDTO inputProductOrderDTO)
{
    Map<String,String> serialNumbersFromToBeValidate = new HashMap<>();
    // 注:原代码条件判断写反,应为CollectionUtils.isNotEmpty
    if (CollectionUtils.isNotEmpty(inputProductOrderDTO.getProductOrderItem()))
    {
        List<IProductOrderItemDTO> productOrderItems = inputProductOrderDTO.getProductOrderItem();
        for (IProductOrderItemDTO productorder : productOrderItems)
        {
            for (IProductOrderItemDTO orderItem : productorder.getProductOrderItem()) {

                List<ICharacteristicDTO> characteristicList = orderItem.getProduct().getProductCharacteristic();
                for(ICharacteristicDTO characteristic : characteristicList)
                {
                    if("SIM".equals(characteristic.getName()))
                    {
                        serialNumbersFromToBeValidate.put(characteristic.getValue(),orderItem.getId());
                    }
                }
            }
        }
    }
    return serialNumbersFromToBeValidate;
}

原代码条件判断CollectionUtils.isEmpty逻辑错误,若不修正永远不会进入循环,重构时会同步修复。

未完成的Stream代码

private Map<String,String> fetchAllSerialNumbers(IProductOrderDTO inputProductOrderDTO)
{
    Map<String,String> serialNumbersFromToBeValidate = inputProductOrderDTO.getProductOrderItem().stream().
            flatMap(orderItem ->orderItem.getProductOrderItem().stream()).
            flatMap(ch -> ch.getProduct().getProductCharacteristic().stream()).
            filter(f->f.getName().equals("SIM")).
            map(ch->ch.getValue()).
            collect(Collectors.toMap(keyMapper, Function.identity()));
    // 无法同时获取特征值(key)和orderItem的ID(value)
    // 需要用map(ch->ch.getValue())作为key
    // 需要从flatMap(orderItem ->orderItem.getProductOrderItem().stream())中获取orderItem的ID作为value
    
    return serialNumbersFromToBeValidate;
}

相关模型接口

public interface IProductOrderItemDTO extends Serializable
{
    public List<IProductOrderItemDTO> getProductOrderItem();
    public void setProductOrderItem(List<IProductOrderItemDTO> productOrderItem);
    public IProductRefOrValueDTO getProduct();
    public void setProduct(IProductRefOrValueDTO product);
    // 补充:原接口缺失getId(),否则原循环代码无法运行
    public String getId();
    public void setId(String id);
}

public interface IProductRefOrValueDTO extends Serializable
{
    public List<ICharacteristicDTO> getProductCharacteristic();
    public void setProductCharacteristic(List<ICharacteristicDTO> productCharacteristic);
}

public interface ICharacteristicDTO extends Serializable
{
    // 补充:原接口缺失必要getter,否则无法判断特征名称和取值
    public String getName();
    public void setName(String name);
    public String getValue();
    public void setValue(String value);
}

完善后的Stream实现

private Map<String, String> fetchAllSerialNumbers(IProductOrderDTO inputProductOrderDTO) {
    // 提前处理空列表,避免空指针
    if (CollectionUtils.isEmpty(inputProductOrderDTO.getProductOrderItem())) {
        return Collections.emptyMap();
    }

    return inputProductOrderDTO.getProductOrderItem().stream()
            // 展开外层orderItem的子orderItem列表
            .flatMap(outerItem -> outerItem.getProductOrderItem().stream())
            // 绑定orderItem与它的特征列表,保留上下文引用
            .flatMap(orderItem -> 
                orderItem.getProduct().getProductCharacteristic().stream()
                        .map(characteristic -> new AbstractMap.SimpleEntry<>(characteristic, orderItem))
            )
            // 过滤出SIM特征
            .filter(entry -> "SIM".equals(entry.getKey().getName()))
            // 收集为目标Map,处理重复key场景
            .collect(Collectors.toMap(
                    entry -> entry.getKey().getValue(),
                    entry -> entry.getValue().getId(),
                    // 重复key时保留第一个值,可根据业务调整策略
                    (existing, replacement) -> existing
            ));
}

关键说明

  • 上下文绑定:通过AbstractMap.SimpleEntry将特征与对应的orderItem绑定,解决Stream操作中丢失orderItem引用的问题,确保能同时获取特征值和orderItem ID。
  • 空值防护:开头直接判断外层列表是否为空,返回空Map避免后续Stream操作抛出空指针异常。
  • 冲突处理:Collectors.toMap的第三个参数用于处理重复key的冲突,这里选择保留第一个出现的值,可根据业务需求改为抛出异常或保留最新值。

内容的提问来源于stack exchange,提问作者Vaibs

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 06:30:37