使用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
相关产品推荐
相关产品推荐

