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

Android中如何比较并合并大小写不同的同名JSON键?

这个问题太常见了——JSON键的大小写不敏感合并确实是日常开发里容易踩的坑,我给你几个实用的解决方案,分场景给你讲清楚:

核心思路

本质上就是要忽略键的大小写差异,先建立一个统一的匹配规则(比如全部转成小写作为匹配标识),然后把API响应里的值对应到预期JSON的键上,嵌套的JSON也可以递归处理。

方案1:基于org.json库(Java)

如果你用的是Java生态里最常用的org.json.JSONObject,可以自己封装一个工具方法来处理,逻辑清晰还灵活:

import org.json.JSONObject;

public class JsonCaseInsensitiveMerge {
    public static void merge(JSONObject targetJson, JSONObject sourceJson) {
        // 先把目标JSON的键转成小写映射,方便快速查找
        JSONObject lowerCaseKeyMap = new JSONObject();
        for (String targetKey : targetJson.keySet()) {
            lowerCaseKeyMap.put(targetKey.toLowerCase(), targetKey);
        }

        // 遍历API响应的每个键
        for (String sourceKey : sourceJson.keySet()) {
            String lowerSourceKey = sourceKey.toLowerCase();
            // 检查目标JSON里有没有匹配的键(大小写不敏感)
            if (lowerCaseKeyMap.has(lowerSourceKey)) {
                String targetKey = lowerCaseKeyMap.getString(lowerSourceKey);
                Object sourceValue = sourceJson.get(sourceKey);
                
                // 如果是嵌套的JSONObject,递归合并
                if (sourceValue instanceof JSONObject && targetJson.get(targetKey) instanceof JSONObject) {
                    merge((JSONObject) targetJson.get(targetKey), (JSONObject) sourceValue);
                } else {
                    // 直接覆盖目标键的值,也可以根据需求改成追加逻辑
                    targetJson.put(targetKey, sourceValue);
                }
            } else {
                // 可选:如果API返回的键在目标里不存在,要不要新增?按需开启
                // targetJson.put(sourceKey, sourceValue);
            }
        }
    }
}

用法示例

// 你原本预期的JSONObject
JSONObject expected = new JSONObject("{\"Name\":\"Alice\",\"Age\":30,\"Contact\":{\"Email\":\"alice@test.com\"}}");
// API返回的响应JSON
JSONObject apiResponse = new JSONObject("{\"name\":\"Alice Smith\",\"age\":31,\"contact\":{\"phone\":\"123456789\"}}");

// 执行合并
JsonCaseInsensitiveMerge.merge(expected, apiResponse);

// 打印合并后的结果
System.out.println(expected.toString(2));

输出结果会保留你预期的键名,同时覆盖/合并API返回的值:

{
  "Name": "Alice Smith",
  "Age": 31,
  "Contact": {
    "Email": "alice@test.com",
    "phone": "123456789"
  }
}

方案2:基于Jackson库(Java)

如果你的项目用Jackson处理JSON,那可以利用它的配置特性来简化操作,不用自己写遍历逻辑:

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonMergeDemo {
    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        // 关键配置:开启大小写不敏感的属性匹配
        mapper.configure(DeserializationFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);

        String expectedJson = "{\"Name\":\"Alice\",\"Age\":30,\"Contact\":{\"Email\":\"alice@test.com\"}}";
        String apiJson = "{\"name\":\"Alice Smith\",\"age\":31,\"contact\":{\"phone\":\"123456789\"}}";

        // 先把预期JSON转成实体类对象
        User user = mapper.readValue(expectedJson, User.class);
        // 用API响应的JSON更新这个对象(自动匹配大小写不敏感的属性)
        mapper.readerForUpdating(user).readValue(apiJson);

        // 再转回JSON,得到合并后的结果
        String mergedJson = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(user);
        System.out.println(mergedJson);
    }

    // 对应你的JSON结构的实体类(可以用Lombok简化getter/setter)
    static class User {
        private String Name;
        private int Age;
        private Contact Contact;

        // 省略getter和setter,或者用@Data注解
        public String getName() { return Name; }
        public void setName(String name) { Name = name; }
        public int getAge() { return Age; }
        public void setAge(int age) { Age = age; }
        public Contact getContact() { return Contact; }
        public void setContact(Contact contact) { Contact = contact; }

        static class Contact {
            private String Email;
            private String phone;

            public String getEmail() { return Email; }
            public void setEmail(String email) { Email = email; }
            public String getPhone() { return phone; }
            public void setPhone(String phone) { this.phone = phone; }
        }
    }
}

通用思路(其他语言)

不管你用Python、JavaScript还是其他语言,核心步骤都是一样的:

  • 第一步:遍历目标JSON的所有键,建立一个「小写键 → 原键名」的映射表
  • 第二步:遍历API响应的每个键,转成小写后去映射表找对应的目标键
  • 第三步:如果找到匹配的键,就把API的值赋值给目标键;如果是嵌套JSON,递归处理
  • 可选:如果API的键在目标里没有匹配,根据需求决定是否新增这个键

比如Python的简单实现示例:

import json

def merge_case_insensitive(target, source):
    # 建立目标键的小写映射
    lower_key_map = {k.lower(): k for k in target}
    
    for source_key, source_val in source.items():
        lower_source_key = source_key.lower()
        if lower_source_key in lower_key_map:
            target_key = lower_key_map[lower_source_key]
            # 递归处理嵌套字典
            if isinstance(source_val, dict) and isinstance(target.get(target_key), dict):
                merge_case_insensitive(target[target_key], source_val)
            else:
                target[target_key] = source_val
        else:
            # 可选:新增不存在的键
            # target[source_key] = source_val
            pass

# 测试
expected = json.loads('{"Name":"Alice","Age":30,"Contact":{"Email":"alice@test.com"}}')
api_response = json.loads('{"name":"Alice Smith","age":31,"contact":{"phone":"123456789"}}')

merge_case_insensitive(expected, api_response)
print(json.dumps(expected, indent=2))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 09:32:45