java - 使用 Gson 将 ArrayList 转换为字符串

标签 java android arraylist gson sharedpreferences

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

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

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

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

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

最佳答案

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

简单的解决方法是使用 TypeToken 并将数据结构更改为多个数组或自定义对象(如 @totoro demo )。

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

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

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;
    }
}

并像这样使用它:

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]]

关于java - 使用 Gson 将 ArrayList 转换为字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37091548/

相关文章:

java - 如何检查相同的 ID,然后为该特定 id 递增?

java - 如何通知当前图层位置变化

android - 在 Jetpack Compose 中保持 Google map 状态

java - 从轨道中删除 MidiEvent 失败 - MIDI/Java

java - 设置JPanel的大小

java - 我如何使用泛型类型的 bean 来创建配置类? (包括示例)

java - “App won' t 运行,除非您使用 Google Maps API 更新 Google Play 服务

java - 创建新文件时的奇怪问题

java - 如何使用 ArrayList 在寄存器中查找名称

java - 删除数组列表中与某个值不匹配的值