【问题标题】:How to convert json to Map<String, Object> making sure integers will be Integer如何将 json 转换为 Map<String, Object> 确保整数为 Integer
【发布时间】:2019-12-14 13:47:33
【问题描述】:

我有一个 json 对象,其中包含嵌套对象,其值为 StringDoubleInteger。当我转换为Map 时,它假设IntegerDouble。我该如何更改?

Map<String, Object> map = response.getJson();

我的回复字段为

{
    ....
    "age" : 14,
    "average" : 12.2,
    ....
}

average 正在正确转换为 Double,但年龄预计为 Integer,但在 Map 中为 convertedDouble

【问题讨论】:

  • JSON 不区分整数和浮点数(而且您没有进行转换,您使用的是基于您正在使用的任何 JSON/web/etc 库的任何转换——*它*进行转换。
  • 你为什么在乎?另外,如果average 恰好是一个整数怎么办?如果您仅根据值应用通用转换,您可能会得到一些average 值作为Integer,而一些作为Double。应该避免这种不一致!这意味着需要指定哪些应该被转换。
  • JavaScript 没有整数。 JSON 中的所有数字都是双精度数。

标签: java json hashmap integer double


【解决方案1】:

您可以通过对Map 进行后处理来做到这一点,在可能的情况下将Double 值转换为Integer,例如

static void convertIntegerToDouble(Map<String, Object> map) {
    Map<String, Object> updates = new HashMap<>();
    for (Iterator<Entry<String, Object>> iter = map.entrySet().iterator(); iter.hasNext(); ) {
        Entry<String, Object> entry = iter.next();
        Object value = entry.getValue();
        if (value instanceof Map) {
            @SuppressWarnings("unchecked")
            Map<String, Object> submap = (Map<String, Object>) value;
            convertIntegerToDouble(submap);
        } else if (value instanceof Double) {
            double d = ((Double) value).doubleValue();
            int i = (int) d;
            if (d == i)
                updates.put(entry.getKey(), i);
        }
    }
    map.putAll(updates);
}

测试

Map<String, Object> map = new HashMap<>(Map.of(
        "A", 42.0,
        "B", new HashMap<>(Map.of(
                "K", 42.0,
                "L", new HashMap<>(Map.of(
                        "R", 42.0,
                        "S", 3.14
                )),
                "M", 3.14
        )),
        "C", 3.14,
        "D", "Foo"
));
System.out.println(map);
convertIntegerToDouble(map);
System.out.println(map);

输出

{A=42.0, B={K=42.0, L={R=42.0, S=3.14}, M=3.14}, C=3.14, D=Foo}
{A=42, B={K=42, L={R=42, S=3.14}, M=3.14}, C=3.14, D=Foo}

【讨论】:

  • 为什么在instanceof Double 测试通过后转换为Double?为什么不使用Double::intValue,因为您使用的是Double::doubleValue
  • @DavidConrad 1) 由于valueObject,因此必须转换为Double 才能调用doubleValue()。 2)intValue()“在缩小原语转换后将Double的值作为int返回”,这也是这段代码正在做的事情,但是对于if (d == i),代码也需要double值测试,所以即使intValue() 也被使用,doubleValue() 也必须被调用。这样,对象上只调用了一个方法。
  • @Andreas 您的解决方案将所有Doubles 转换为Integers,我只需要将一个Double 转换为Integer
  • @Logic 为什么你认为它将所有Doubles 转换为Integers?测试代码是专门编写的,以表明它没有,如 output 所示,其中 42.0 (double) 被转换为 42 (int),但 3.14 (double) 没有被转换,因为它不能在没有价值损失的情况下被转换,这是代码中if (d == i) 检查的全部要点。
  • @Logic “我只需要转换一个Double 如果您费心回复my comment 来回答您的问题,也许您可​​能会得到一个更好的仅更改特定命名属性的值的解决方案。 --- 但是话又说回来,如果解决方案就像获取特定命名属性的值并转换其类型一样简单,那么您真的需要给出这样简单的代码吗?自己做吧。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-10
  • 1970-01-01
  • 2019-12-06
  • 1970-01-01
  • 1970-01-01
  • 2015-06-24
  • 1970-01-01
相关资源
最近更新 更多