使用 Gson 将 ArrayList 转换为字符串 [英] Convert ArrayList with Gson to String

查看:115
本文介绍了使用 Gson 将 ArrayList 转换为字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含 ArrayListsArrayList,根列表中的每个 ArrayList 包含一个 ArrayList ArrayListcode>Integers 和 Strings 之一.我正在使用 Gson 将其转换为字符串以使用 SharedPreferences 保存它.但是当我重新转换它时,Gson 给了我 2.131558489E9 而不是原始的 int 2131558489.我该如何解决这个问题?最好的问候.

这是我转换 ArrayList 的方法:levelPattern 是 ArrayList

String levelPatternGson = new Gson().toJson(levelPattern);

这就是我将它转换回来的方式:

levelPattern = new Gson().fromJson(levelPatternGson, ArrayList.class);

解决方案

整数和双精度的json标准没有区别,只有数字类型.这就是为什么如果你不给他你想要的类型,默认情况下 gson 会将数字转换为双精度数.

简单的修复方法是使用 TypeToken 并将数据结构更改为多个数组或自定义对象(如在 @totoro 演示).

new Gson().fromJson(levelPatternGson, new TypeToken>() {}.getType());

但您也可以编写自定义列表反序列化器:

公共静态类 ListDeserializerDoubleAsIntFix 实现 JsonDeserializer{@Override @SuppressWarnings("unchecked")public List deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) 抛出 JsonParseException {返回(列表)读取(json);}公共对象读取(JsonElement 中){if(in.isJsonArray()){列表<对象>list = new ArrayList();JsonArray arr = in.getAsJsonArray();for (JsonElement anArr : arr) {list.add(read(anArr));}退货清单;}else if(in.isJsonObject()){映射<字符串,对象>map = new LinkedTreeMap();JsonObject obj = in.getAsJsonObject();设置>entitySet = obj.entrySet();for(Map.Entry entry: entitySet){map.put(entry.getKey(), read(entry.getValue()));}返回地图;}else if( in.isJsonPrimitive()){JsonPrimitive prim = in.getAsJsonPrimitive();如果(prim.isBoolean()){返回 prim.getAsBoolean();}else if(prim.isString()){返回 prim.getAsString();}else if(prim.isNumber()){Number num = prim.getAsNumber();//在这里你可以处理双 int/long 值//并返回任何你想要的类型//此解决方案会将 3.0 float 转换为 long 值if(Math.ceil(num.doubleValue()) == num.longValue())返回 num.longValue();别的{返回 num.doubleValue();}}}返回空;}}

并像这样使用它:

GsonBuilder builder=new GsonBuilder();列表<列表>levelPattern = Arrays.asList(Arrays.asList(2131558489L, 2L, 3L),Arrays.asList("一", "二", "三"));String levelPatternGson = new Gson().toJson(levelPattern);列表 levelPattern2 = new GsonBuilder().registerTypeAdapter(List.class, new ListDeserializerDoubleAsIntFix()).创建().fromJson(levelPatternGson, List.class);System.out.println(levelPattern2);

<块引用>

Json: [[2131558489,2,3],["一","二","三"]]

输出:[[2131558489, 2, 3], [一, 二, 三]]

I have an ArrayList which contains ArrayLists, each ArrayList in the Root list contains one ArrayList of Integers and one of Strings. I am converting it with Gson to a String to save it with SharedPreferences. But when I am reconverting it, Gson gives me 2.131558489E9 instead of the original int 2131558489. How can I fix this Problem? Best Regards.

Here is how I convert the ArrayList: levelPattern is the ArrayList

String levelPatternGson = new Gson().toJson(levelPattern);

And this is how I convert it back:

levelPattern = new Gson().fromJson(levelPatternGson, ArrayList.class);

解决方案

There is no difference in json standard between integers and doubles, there is only number type. That is why gson by default converts numbers to doubles if you don't give him what type you want.

Easy fix would be to use TypeToken and change data structure to multiple arrays or custom object (like in @totoro demo).

new Gson().fromJson(levelPatternGson, new TypeToken<List<Integer>>() {}.getType());

But you could also write custom List deserializer:

public static class ListDeserializerDoubleAsIntFix implements JsonDeserializer<List>{

    @Override  @SuppressWarnings("unchecked")
    public List deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        return (List) read(json);
    }

    public Object read(JsonElement in) {

        if(in.isJsonArray()){
            List<Object> list = new ArrayList<Object>();
            JsonArray arr = in.getAsJsonArray();
            for (JsonElement anArr : arr) {
                list.add(read(anArr));
            }
            return list;
        }else if(in.isJsonObject()){
            Map<String, Object> map = new LinkedTreeMap<String, Object>();
            JsonObject obj = in.getAsJsonObject();
            Set<Map.Entry<String, JsonElement>> entitySet = obj.entrySet();
            for(Map.Entry<String, JsonElement> entry: entitySet){
                map.put(entry.getKey(), read(entry.getValue()));
            }
            return map;
        }else if( in.isJsonPrimitive()){
            JsonPrimitive prim = in.getAsJsonPrimitive();
            if(prim.isBoolean()){
                return prim.getAsBoolean();
            }else if(prim.isString()){
                return prim.getAsString();
            }else if(prim.isNumber()){
                Number num = prim.getAsNumber();
                // here you can handle double int/long values
                // and return any type you want
                // this solution will transform 3.0 float to long values
                if(Math.ceil(num.doubleValue())  == num.longValue())
                    return num.longValue();
                else{
                    return num.doubleValue();
                }
            }
        }
        return null;
    }
}

and use it like this:

GsonBuilder builder=new GsonBuilder();
List<List> levelPattern = Arrays.asList(Arrays.asList(2131558489L, 2L, 3L), 
                                        Arrays.asList("one", "two", "three"));
String levelPatternGson = new Gson().toJson(levelPattern);
List levelPattern2 = new GsonBuilder()
        .registerTypeAdapter(List.class, new ListDeserializerDoubleAsIntFix())
        .create()
        .fromJson(levelPatternGson, List.class);

System.out.println(levelPattern2);

Json: [[2131558489,2,3],["one","two","three"]]

Output: [[2131558489, 2, 3], [one, two, three]]

这篇关于使用 Gson 将 ArrayList 转换为字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆