如何防止gson将整数转换为双精度

亚历克斯

我的json中有整数,并且我不希望gson将其转换为双精度。以下内容不起作用:

@Test
public void keepsIntsAsIs(){
    String json="[{\"id\":1,\"quantity\":2,\"name\":\"apple\"},{\"id\":3,\"quantity\":4,\"name\":\"orange\"}]";
    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(Double.class,  new DoubleSerializerAsInt());
    Gson gson = gsonBuilder.create();
    List<Map<String, Object>> l = gson.fromJson(json, List.class);
    for(Map<String, Object> item : l){
        System.out.println(item);
    }
}

private static class DoubleSerializerAsInt implements JsonSerializer<Double>{

    @Override
    public JsonElement serialize(Double aDouble, Type type, JsonSerializationContext jsonSerializationContext) {
        int value = (int)Math.round(aDouble);
        return new JsonPrimitive(value);
    }
}

输出不是我想要的:

{id=1.0, quantity=2.0, name=apple}
{id=3.0, quantity=4.0, name=orange}

有没有办法在我的地图中使用整数而不是双精度?

{id=1, quantity=2, name=apple}
{id=3, quantity=4, name=orange}

编辑:不是我所有的字段都是整数。我已经相应地修改了我的示例。我已经在线阅读了很多示例,包括此站点上的一些答案,但是在特定情况下不起作用。

干:

1)您必须创建自定义JsonDeserializer而不是JsonSerializer您的问题。

2)我不认为这种行为来自Double解串器。它更像是json对象/地图问题

这是源代码

case NUMBER:
      return in.nextDouble();

因此,您可以尝试使用自定义反序列化器的方法Map<String, Object>(或者,如果需要,可以使用一些更通用的映射):

public static class MapDeserializerDoubleAsIntFix implements JsonDeserializer<Map<String, Object>>{

    @Override  @SuppressWarnings("unchecked")
    public Map<String, Object> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        return (Map<String, Object>) 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;
    }
}

要使用它,你必须给予适当的TypeTokenregisterTypeAdaptergson.fromJson功能:

String json="[{\"id\":1,\"quantity\":2,\"name\":\"apple\"}, {\"id\":3,\"quantity\":4,\"name\":\"orange\"}]";

GsonBuilder gsonBuilder = new GsonBuilder();

gsonBuilder.registerTypeAdapter(new TypeToken<Map <String, Object>>(){}.getType(),  new MapDeserializerDoubleAsIntFix());

Gson gson = gsonBuilder.create();
List<Map<String, Object>> l = gson.fromJson(json, new TypeToken<List<Map<String, Object>>>(){}.getType() );

for(Map<String, Object> item : l)
    System.out.println(item);

String serialized = gson.toJson(l);
System.out.println(serialized);

结果:

{id=1, quantity=2, name=apple}
{id=3, quantity=4, name=orange}
Serialized back to: [{"id":1,"quantity":2,"name":"apple"},{"id":3,"quantity":4,"name":"orange"}]

PS:这只是您可以尝试的另一种选择。就我个人而言,我想为您的json创建自定义对象,而不是List<Map<String, Integer>>更酷,更易于阅读的方式

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何将双精度变量转换为整数变量?

将双精度数转换为整数尾数和指数

将双精度转换为整数时出错

(C++) 试图将双精度转换为整数(解释)

无法将字符串转换为整数或双精度

如何在C ++中安全地将双精度型转换为整数?

如何将数字从双精度转换为整数而不进行舍入?

如何将双精度数转换为最接近的整数值?

如何使用sql查询将字符串转换为整数或双精度数

如何使用联合将双精度位逐位转换为 64 位整数

将类型转换为双精度整数以从类型转换的整数除法中获得双精度结果

Typedef转换为双精度整数

Haskell-将整数转换为双精度,然后转换为字符串

如何将字符串从双精度转换为双精度*

将双精度对转换为双精度数组

如何在避免不确定行为的情况下将任意双精度数转换为整数?

整数转换为双精度数时会失去精度吗?

将小数转换为双精度

将浮点向量转换为双精度

将双精度转换为日期

将双精度转换为日期格式

如何测试无损双精度/整数转换?

C#在转换为字符串时如何防止双精度值截断

Kotlin:将双精度数转换为整数时会发生ClassCastException吗?

将双精度数组列表转换为整数数组列表

Java-将小时数(双精度)转换为分钟数(整数),反之亦然

将 3 个 RGB 整数转换为一个 0-1 双精度

使用可编码将字符串转换为日期/整数/双精度

R:根据列索引将数据帧值从整数转换为双精度