简体   繁体   English

将ArrayList与Gson转换为String

[英]Convert ArrayList with Gson to String

I have an ArrayList which contains ArrayLists , each ArrayList in the Root list contains one ArrayList of Integers and one of Strings . 我有一个ArrayList含有ArrayLists ,每一个ArrayList的根列表中包含一个ArrayListIntegers和一个Strings I am converting it with Gson to a String to save it with SharedPreferences. 我正在将它与Gson转换为String以使用SharedPreferences保存它。 But when I am reconverting it, Gson gives me 2.131558489E9 instead of the original int 2131558489 . 但是当我重新转换它时,Gson给了我2.131558489E9而不是原来的int 2131558489 How can I fix this Problem? 我该如何解决这个问题? Best Regards. 最好的祝福。

Here is how I convert the ArrayList: levelPattern is the ArrayList 这是我如何转换ArrayList:levelPattern是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. 整数和双精度之间的json标准没有区别,只有数字类型。 That is why gson by default converts numbers to doubles if you don't give him what type you want. 这就是为什么gson默认情况下会将数字转换为双精度,如果你不给他你想要的类型。

Easy fix would be to use TypeToken and change data structure to multiple arrays or custom object (like in @totoro demo ). 简单的解决方法是使用TypeToken并将数据结构更改为多个数组或自定义对象(如@totoro 演示 )。

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

But you could also write custom List deserializer: 但您也可以编写自定义List反序列化器:

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"]] Json:[[2131558489,2,3],[“one”,“two”,“three”]]

Output: [[2131558489, 2, 3], [one, two, three]] 输出:[[2131558489,2,3],[一,二,三]]

I am not sure I understand the question completely... 我不确定我完全理解这个问题......

I am assuming your ArrayList is not using generics. 我假设你的ArrayList没有使用泛型。

This solution is a generics version, using an Object to hold the two different typed ArrayList s. 此解决方案是泛型版本,使用Object来保存两个不同类型的ArrayList

class Test {

    static class Bar {
        private List<Integer> integers;
        private List<String> strings;
    }

    public static void main(String[] argv) {
        Type baseType = new TypeToken<List<Bar>>() {}.getType();
        List<Bar> foos = new ArrayList<>();

        Bar bar;

        bar = new Bar();
        bar.integers = Arrays.asList(1, 2, 3, 4);
        bar.strings = Arrays.asList("a", "b", "c", "d");
        foos.add(bar);

        bar = new Bar();
        bar.integers = Arrays.asList(5, 6, 7, 2131558489);
        bar.strings = Arrays.asList("e", "f", "g", "h");
        foos.add(bar);

        Gson gson = new Gson();
        String tmp = gson.toJson(foos, baseType);
        System.out.println(tmp);
        foos = gson.fromJson(tmp, baseType);
        System.out.print(foos.get(1).integers.get(3));
    }
}

Output 产量

JSON: [{"integers":[1,2,3,4],"strings":["a","b","c","d"]},{"integers":[5,6,7,2131558489],"strings":["e","f","g","h"]}] JSON:[{“整数”:[1,2,3,4],“字符串”:[“a”,“b”,“c”,“d”]},{“整数”:[5,6 ,7,2131558489], “字符串”:[ “E”, “F”, “G”, “H”]}]

The Integer: 2131558489 整数:2131558489

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM