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

使用Gson提取JSON中data转为HashMap遇类型转换异常求解

解决Gson转换时LinkedTreeMap转HashMap的ClassCastException问题

问题场景

你有如下JSON数据:

{
  "data": {
    "category": {
      "name_en": "Trend",
      "style": "normal"
    },
    "items": [
      {
        "title_en": "The Garfield Movie",
        "imdb_rank": 5.8,
        "country": "US",
        "company": " Columbia Pictures"
      }
    ]
  },
  "type": "category"
}

你想要获取data值并使用items数组,尝试了以下代码:

map = new Gson().fromJson(
    new Gson().toJson((HashMap<String, Object>) map.get("data")),
    new TypeToken<HashMap<String, Object>>() {}.getType()
);

但出现了类型转换错误:

07-09 19:50:16.615 12794 12794 E AndroidRuntime: java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to java.util.HashMap

错误原因

Gson在解析无明确类型的Object时,默认会用自身实现的LinkedTreeMap存储键值对,而非java.util.HashMap,直接强转必然抛出ClassCastException。

解决方案

方法一:直接转换LinkedTreeMap到HashMap

无需二次序列化(转JSON再解析),利用HashMap的构造方法直接完成转换:

// 假设map是已解析得到的根级Map
LinkedTreeMap<String, Object> dataLinkedMap = (LinkedTreeMap<String, Object>) map.get("data");
HashMap<String, Object> dataMap = new HashMap<>(dataLinkedMap);

// 获取并使用items数组
List<LinkedTreeMap<String, Object>> items = (List<LinkedTreeMap<String, Object>>) dataMap.get("items");
for (LinkedTreeMap<String, Object> item : items) {
    String title = (String) item.get("title_en");
    double imdbRank = (double) item.get("imdb_rank");
    String country = (String) item.get("country");
    String company = (String) item.get("company");
}

方法二:直接解析整个JSON为目标类型

如果还未进行初始解析,可直接把整个JSON字符串解析为根级HashMap,再提取转换data:

String jsonStr = "你的JSON字符串内容";
// 解析根级数据
Type rootType = new TypeToken<HashMap<String, Object>>() {}.getType();
HashMap<String, Object> rootMap = new Gson().fromJson(jsonStr, rootType);

// 转换data为HashMap
LinkedTreeMap<String, Object> dataLinkedMap = (LinkedTreeMap<String, Object>) rootMap.get("data");
HashMap<String, Object> dataMap = new HashMap<>(dataLinkedMap);

方法三:更推荐的方式——使用实体类(类型安全,适合新手)

实体类可以避免频繁类型转换,代码可读性和安全性更高,根据JSON结构定义对应类:

// 根响应类
class RootResponse {
    private Data data;
    private String type;

    // Getter和Setter方法
    public Data getData() { return data; }
    public void setData(Data data) { this.data = data; }
    public String getType() { return type; }
    public void setType(String type) { this.type = type; }
}

// Data类
class Data {
    private Category category;
    private List<Item> items;

    // Getter和Setter方法
    public Category getCategory() { return category; }
    public void setCategory(Category category) { this.category = category; }
    public List<Item> getItems() { return items; }
    public void setItems(List<Item> items) { this.items = items; }
}

// Category类
class Category {
    private String name_en;
    private String style;

    // Getter和Setter方法
    public String getName_en() { return name_en; }
    public void setName_en(String name_en) { this.name_en = name_en; }
    public String getStyle() { return style; }
    public void setStyle(String style) { this.style = style; }
}

// Item类
class Item {
    private String title_en;
    private double imdb_rank;
    private String country;
    private String company;

    // Getter和Setter方法
    public String getTitle_en() { return title_en; }
    public void setTitle_en(String title_en) { this.title_en = title_en; }
    public double getImdb_rank() { return imdb_rank; }
    public void setImdb_rank(double imdb_rank) { this.imdb_rank = imdb_rank; }
    public String getCountry() { return country; }
    public void setCountry(String country) { this.country = country; }
    public String getCompany() { return company; }
    public void setCompany(String company) { this.company = company; }
}

直接解析JSON到实体类,便捷获取数据:

String jsonStr = "你的JSON字符串内容";
RootResponse response = new Gson().fromJson(jsonStr, RootResponse.class);

// 获取data和items
Data data = response.getData();
List<Item> items = data.getItems();

// 遍历使用items数据
for (Item item : items) {
    System.out.println("电影标题:" + item.getTitle_en());
    System.out.println("IMDB评分:" + item.getImdb_rank());
    System.out.println("国家:" + item.getCountry());
    System.out.println("出品公司:" + item.getCompany());
}

这种方式无需处理复杂类型转换,IDE还能提供代码提示,非常适合新手维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 03:52:35