gson转化为带泛型的Map(K, V):com.google.gson.internal.LinkedTreeMap cannot be cast to xx(entity)

 

目录

错误日志:

解释:

原因:

错误代码:

解决方法

(零)、TypeToken解决

其他几种解决思路

(一)、当Map的Key为String类型时

正确代码1:

(二)、通过 由Map的key组成的List,和有value组成的List解决

正确代码2:


错误日志:

    com.google.gson.internal.LinkedTreeMap cannot be cast to xx(entity)

解释:

    LinkedTreeMap 得到的对象无法被映射到实体类

原因:

    带泛型的map被转成gson后,对象被擦除,变为无属性的Object。所以无法被还原。

错误代码:

public  Map toMap2(String json, Class kClazz, Class vClazz) {
    return sGson.fromJson(json, new TypeToken>() {}.getType());
}

解决方法

(零)、TypeToken解决

    /**
     * @param json map的序列化结果
     * @param    k类型
     * @param    v类型
     * @return Map
     */
    public  Map toMap(String json, Class kClazz, Class vClazz) {
        return sGson.fromJson(json,TypeToken.getParameterized(Map.class,kClazz,vClazz).getType());
    }

其他几种解决思路

(一)、当Map的Key为String类型时

    为什么要特别说明为key为String呢,因为不管你的Key为什么类型,通过Gson还原时得到的LinkedTreeMap 的 key都为String类型。

    此时通过JsonObject即可解决

正确代码1:

    public  Map toStringKeyMap(String json, Class vClazz) {
        Map map = new HashMap<>();
        try {
            JsonObject obj = new JsonParser().parse(json).getAsJsonObject();
            Set> entrySet = obj.entrySet();
            for (Map.Entry entry : entrySet) {
                String entryKey = entry.getKey();
                JsonObject object = (JsonObject) entry.getValue();
                V value = sGson.fromJson(object, vClazz);
                map.put(entryKey, value);
            }
        } catch (Exception e) {
            return null;
        }
        return map;
    }

你可能会问,那怎么不用JsonObject转化 JsonObject kobject = (JsonObject) entry.getKey() , 那样不就解决问题了

因为Key被映射为String类型了,目前还没找到解决办法,也不打算在这中地方深追下去了,太费时间了。

(二)、通过 由Map的key组成的List,和有value组成的List解决

思路:先得到由Map的Key组成的keyList,再得到由value组成的valueList;之后分别序列化keyList、valueList。反序列化时,也是分别对keyList和valueList反序列化,在依次添加到map中去

正确代码2:

(1)得到keyList和vList

/**
     * @param map map对象
     * @param  k类型
     * @param  v类型
     * @return keyList
     */
    public static  List getMapKeyList(Map map, Class kClazz, Class vClazz) {
        List keyList = new ArrayList<>();
        for (Map.Entry entry : map.entrySet()) {
            keyList.add(entry.getKey());
        }
        return keyList;
    }

    /**
     * @param map     map对象
     * @param keyList 由map的key组成的keyList
     * @param      k类型
     * @param      v类型
     * @return valueList
     */
    public static  List getMapValueListByKey(Map map, List keyList, Class kClazz, Class vClazz) {
        List valueList = new ArrayList<>();

        for (K k : keyList) {
            V v = map.get(k);
            valueList.add(v);
        }

        return valueList;
    }

(2)序列化keyList和valueList

    private Gson sGson = new Gson();

    public String toJson(Object object) {
        return sGson.toJson(object);
    }

(3)反序列化keyList和valueList,得到map

    /**
     * @param kJson keyList的序列化结果
     * @param vJson valueList的序列化结果
     * @param    k类型
     * @param    v类型
     * @return Map
     */
    public  Map toMap(String kJson, String vJson, Class kClazz, Class vClazz) {
        Map map = new HashMap<>();
        try {
            List kList = toList(kJson, kClazz);
            List vList = toList(vJson, vClazz);
            for (int i = 0; i < kList.size(); i++) {
                K k = kList.get(i);
                V v = vList.get(i);
                map.put(k, v);
            }
        } catch (Exception e) {
            return null;
        }
        return map;
    }

    /**
     * @param json list的序列化字符串
     * @param   T类型
     * @return List
     */
    public  List toList(String json, Class clazz) {
        List list = new ArrayList<>();
        try {
            JsonArray array = new JsonParser().parse(json).getAsJsonArray();
            for (final JsonElement elem : array) {
                list.add(new Gson().fromJson(elem, clazz));
            }
        } catch (Exception e) {
            return null;
        }
        return list;
    }

 

你可能感兴趣的:(android,进阶)