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

使用Gson解析含大量相似字段的JSON,获取非空字段方法问询

解决Gson解析多字段JSON并快速获取非空字段的方案

当然可以用HashMap来存储字段,还有几种更实用的方案,根据你的需求选择:

方案一:直接用HashMap接收Rates数据

这是最省事的办法,不用定义几百个字段的Rates类,Gson能直接把JSON里的rates对象解析成HashMap<String, Integer>:

// 假设你的JSON外层包含rates字段,示例结构:{"rates": {"first":1, "second":2, ...}}
String jsonResponse = "你的JSON响应字符串";
JsonObject root = new Gson().fromJson(jsonResponse, JsonObject.class);
// 解析rates为HashMap
HashMap<String, Integer> ratesMap = new Gson().fromJson(
    root.get("rates"),
    new TypeToken<HashMap<String, Integer>>() {}.getType()
);

// 过滤出所有非空字段
Map<String, Integer> nonNullRates = ratesMap.entrySet().stream()
    .filter(entry -> entry.getValue() != null)
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
  • 优点:完全不用维护冗长的实体类,过滤非空字段一步到位
  • 缺点:失去实体类的类型约束,如果JSON字段值类型突然变化(比如从数字变成字符串),解析会报错

方案二:改造Rates类,集成非空字段收集方法

如果需要保留Rates实体类(比如依赖字段的类型提示),可以给类加个方法来收集非空字段:

方式A:手动编写收集逻辑(适合字段固定的场景)

public class Rates {
    @SerializedName("first")
    private Integer first;
    @SerializedName("second")
    private Integer second;
    @SerializedName("third")
    private Integer third;
    // ... 其他几百个字段

    // 收集所有非空字段的方法
    public Map<String, Integer> getNonNullFields() {
        Map<String, Integer> nonNullMap = new HashMap<>();
        if (first != null) nonNullMap.put("first", first);
        if (second != null) nonNullMap.put("second", second);
        if (third != null) nonNullMap.put("third", third);
        // ... 其他字段依次添加判断
        return nonNullMap;
    }
}
  • 优点:类型安全,没有反射带来的性能损耗
  • 缺点:初次编写需要逐个字段加判断,比较繁琐,但后续维护简单

方式B:反射自动收集(适合字段频繁变动的场景)

public class Rates {
    // ... 你的字段定义

    public Map<String, Integer> getNonNullFields() throws IllegalAccessException {
        Map<String, Integer> nonNullMap = new HashMap<>();
        Field[] fields = this.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            Object value = field.get(this);
            if (value != null) {
                // 优先用@SerializedName的注解值作为键,没有则用字段名
                SerializedName annotation = field.getAnnotation(SerializedName.class);
                String key = annotation != null ? annotation.value() : field.getName();
                nonNullMap.put(key, (Integer) value);
            }
        }
        return nonNullMap;
    }
}
  • 优点:新增字段后自动生效,不用手动修改收集逻辑
  • 缺点:反射有轻微性能损耗,需要处理类型转换异常(如果字段类型不是Integer)

方案三:用Gson的JsonObject直接处理

既不想用HashMap也不想定义实体类的话,可以直接解析成JsonObject,遍历过滤非空:

String jsonResponse = "你的JSON响应字符串";
JsonObject root = new Gson().fromJson(jsonResponse, JsonObject.class);
JsonObject ratesObj = root.getAsJsonObject("rates");

Map<String, Integer> nonNullRates = new HashMap<>();
for (Map.Entry<String, JsonElement> entry : ratesObj.entrySet()) {
    if (!entry.getValue().isJsonNull()) {
        nonNullRates.put(entry.getKey(), entry.getValue().getAsInt());
    }
}
  • 优点:灵活,不需要预定义结构,适合JSON字段经常变化的场景
  • 缺点:需要手动处理类型转换,没有类型安全保障

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 20:33:28