【问题标题】:Convert json to corresponding HashMap将json转换为对应的HashMap
【发布时间】:2015-03-06 12:07:28
【问题描述】:

当使用 gson 将 json 转换为 Map 时,我们有一个 LinkedTreeMap 实例,其所有值都是 String 或 Boolean...偶数被转换为 String...

Gson gson = new GsonBuilder().create();
Map<String, Object> result = gson.fromJson(EXAMPLE, new TypeToken<Map<String,Object>>() {}.getType());

我们如何将 json 转换为具有相应原始包装器的最简单的 HashMap?在这种情况下,性能也非常重要......我想创建尽可能少的垃圾并重用解析器......

有没有办法使用 gson 来做到这一点?或任何其他库?

请不要建议为每个 json 创建特殊的 java 类型...我宁愿浏览 trough map...

这是一个例子

{                           // Hashmap (as no ordering or sorting is essential)
  "bool": true,             // Boolean
  "string": "string",       // String
  "int" : 123,              // Long for all non floats are ok but if possible i'd like this to be Integer if it fits, otherwise Long
  "long" : 100000000000000, // Long if Integer cant contain the number...
  "double" : 123.123435,    // all floating point nubmers will just map to Double
  "object" : {              // another HashMap
    ...
  }
  "array" : [               // Array or some collection like ArrayList or LinkedList
    ...
  ]
}

目标是尽可能快将任何json转换为java Map(如果json的根是数组,则为Array),然后使用一些访问器方法来访问数据......而不是发明java为每个可能的 json 结构输入类型...

【问题讨论】:

  • 你能发布一个你的json的例子吗?
  • 我会更新问题,以便您明白我的意思... Json 可以是任何东西,主要是浮点值,我希望在 HashMap 中作为 Double 和 Strings (如排序或排序一样)在这里没有任何意义)...
  • 任何体面的 JSON 解析器,如果使用得当,应该能够将其解析为 Maps 和 Lists,并为原语使用适当的数据类型。至于速度,所有 JSON 解析器都声称“快”,因此您可能需要对自己喜欢的进行基准测试。
  • @HotLicks 例如,您如何使 GSON 或任何您已知的库解析为 HashMaps(这意味着您不关心排序或排序)?因为在我看来,大多数人都认为您确实关心并使用 LinkedSomething... 这不是内存效率并且会产生大量垃圾...
  • 我现在正在考虑来自 OpenHFT 的这个 SAXophone 项目,我必须在其中实现逐个符号的解析...

标签: java json performance parsing gson


【解决方案1】:

适用于 Jackson Databind 库:

ObjectMapper mapper = new ObjectMapper();
Map<String, Object> map = mapper.readValue(jsonString, Map.class);

地图中的值将是它们对应的类型。 此测试通过:

    @Test
    public void test() throws Exception {
        String jsonString = "{\"bool\": true,"
                + "\"str\":\"strv\","
                + "\"long\": 100000000000000}";
        ObjectMapper mapper = new ObjectMapper();
        Map<String, Object> map = mapper.readValue(jsonString , Map.class);

        assertEquals(Long.class, map.get("long").getClass());
        assertEquals(Boolean.class, map.get("bool").getClass());
    }

【讨论】:

  • 我尝试了您的代码 sn-p,它的工作原理与 Gson 完全相同,只是它使用 LinkedHashMap 而不是 LinkedTreeMap...并且所有值都是字符串或布尔值...
  • 你确定杰克逊会这样做吗?也许有一种方法可以将它们配置为通过构建器或其他东西来实现这种行为......
  • @Vach -- 也许你应该向我们展示一小部分你的真实数据。
  • @HotLicks 不确定这是否有意义,但你可以去i.imgur.com/AWQxp00.png
  • @Vach - 再次访问 json.org 并研究语法。 “id”的值是一个字符串,因为它用引号引起来。是的,解析器正在使用 LinkedHashMap,但该解析器所做的是(因为许多愚蠢的 JSON 用户——尤其是 Java 用户——需要它)。其他解析器不会。大多数使用解析器的人都不会注意到其中的区别——找到一个不使用 LinkedHashMap 的唯一方法是找到一个愚蠢的 JSON 用户抱怨过的那个。或者自己测试一下。
猜你喜欢
  • 1970-01-01
  • 2016-12-07
  • 1970-01-01
  • 2019-05-17
  • 2010-10-21
  • 1970-01-01
  • 2014-03-10
  • 1970-01-01
相关资源
最近更新 更多