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

如何在嵌套Map中实现值补丁?避免覆盖非目标原有值

嵌套Map的深度合并(补丁)解决方案

问题分析

直接使用putAll()或replaceAll()会直接替换目标Map中的整个子Map条目(比如示例中的validFor),导致原Map子结构中的未被覆盖字段丢失(如startDateTime)。要实现仅更新指定键值、保留其他原有数据的需求,需要深度遍历嵌套Map,逐层合并键值。

原生Java递归实现

以下是自定义的深度合并工具方法,可处理任意层级的嵌套Map:

import java.util.Map;

public class MapMergeUtil {
    @SuppressWarnings("unchecked")
    public static void deepMerge(Map<String, Object> targetMap, Map<String, Object> sourceMap) {
        for (Map.Entry<String, Object> entry : sourceMap.entrySet()) {
            String key = entry.getKey();
            Object sourceVal = entry.getValue();
            Object targetVal = targetMap.get(key);

            // 若当前值为嵌套Map,则递归合并
            if (sourceVal instanceof Map && targetVal instanceof Map) {
                deepMerge((Map<String, Object>) targetVal, (Map<String, Object>) sourceVal);
            } else {
                // 非嵌套结构直接替换值
                targetMap.put(key, sourceVal);
            }
        }
    }
}

使用示例

import java.util.HashMap;
import java.util.Map;

public class Main {
    public static void main(String[] args) {
        // 初始化第一个Map(目标Map)
        Map<String, Object> firstMap = new HashMap<>();
        firstMap.put("atBaseType", "abc");
        firstMap.put("atType", "abc");
        firstMap.put("id", "ot10");
        firstMap.put("name", "ot10");
        firstMap.put("version", "1.0");

        Map<String, Object> validFor = new HashMap<>();
        validFor.put("endDateTime", "2023-02-25T00:00:00Z");
        validFor.put("startDateTime", "2023-02-01T00:00:00Z");
        firstMap.put("validFor", validFor);

        // 初始化第二个Map(补丁Map)
        Map<String, Object> secondMap = new HashMap<>();
        Map<String, Object> newValidFor = new HashMap<>();
        newValidFor.put("endDateTime", "2023-04-25T00:00:00Z");
        secondMap.put("validFor", newValidFor);

        // 执行深度合并(直接修改firstMap)
        MapMergeUtil.deepMerge(firstMap, secondMap);

        // 输出结果
        System.out.println(firstMap);
    }
}

执行后,firstMap的validFor字段会保留startDateTime,同时更新endDateTime为补丁值,完全符合预期结果。

第三方库简化实现

如果不想自己实现递归逻辑,可以使用第三方工具库:

Apache Commons Collections

使用MapUtils.merge()方法,自动处理嵌套Map的合并:

import org.apache.commons.collections4.MapUtils;

// 合并后返回新Map,不修改原Map
Map<String, Object> mergedMap = MapUtils.merge(firstMap, secondMap);

Guava

Guava的Maps类结合递归逻辑,可实现深度合并:

import com.google.common.collect.Maps;

Map<String, Object> mergedMap = Maps.merge(firstMap, secondMap, (oldVal, newVal) -> {
    if (oldVal instanceof Map && newVal instanceof Map) {
        return Maps.merge((Map<String, Object>) oldVal, (Map<String, Object>) newVal, (o, n) -> n);
    }
    return newVal;
});

注意事项

  • 如果需要保留原Map不被修改,需先对目标Map进行深拷贝(浅拷贝仅复制顶层引用,嵌套Map仍会被修改),再执行合并操作。
  • 递归实现需注意Map类型的统一(示例中使用Map<String, Object>适配通用场景)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 00:25:06