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

