【问题标题】:Convert Guava HashMultimap to json将 Guava HashMultimap 转换为 json
【发布时间】:2014-09-04 19:57:15
【问题描述】:

我想将 HashMultiMap 打印为 json。

HashMultimap<String,Object> multimap = HashMultimap.create();
multimap.put("a",Obj1);
multimap.put("a",Obj3);
multimap.put("b",Obj2);

{ 
  "a":[Obj1,Obj3],
  "b":[Obj2]
}

Obj1 和其他对象应该再次在 json 中(为了保持干净,我已将其显示为对象)
我可以遍历各个键并使用 Gson 等库将一组对象转换为 json。

但要获取 HashMultimap 的整个快照,我想将其转换为 json 并检查它。

Gson 不能转换整个地图,但可以做个别值(对象列表到 json)

【问题讨论】:

    标签: json gson guava multimap


    【解决方案1】:

    首先在 MultiMap 上调用asMap()。这会将 MultiMap 转换为标准 Map,其中每个值都是一个 Collection。

    在您的示例中,生成的 Map 的类型是 Map&lt;String, Collection&lt;Object&gt;&gt;。 Gson 应该能够正确序列化它。

    【讨论】:

    • 是的,在发布问题后检查了这个 API :)。感谢您指出。
    • @sat 当您使用适配器时,这一切都会自动发生。
    【解决方案2】:

    您需要编写JsonAdapterJsonDeserializerJsonSerializer。很糟糕,但我想试试。

    基本上,您将所有内容委托给Map&lt;String, Collection&lt;V&gt;&gt;

    static class MultimapAdapter implements JsonDeserializer<Multimap<String, ?>>, JsonSerializer<Multimap<String, ?>> {
        @Override public Multimap<String, ?> deserialize(JsonElement json, Type type,
                JsonDeserializationContext context) throws JsonParseException {
            final HashMultimap<String, Object> result = HashMultimap.create();
            final Map<String, Collection<?>> map = context.deserialize(json, multimapTypeToMapType(type));
            for (final Map.Entry<String, ?> e : map.entrySet()) {
                final Collection<?> value = (Collection<?>) e.getValue();
                result.putAll(e.getKey(), value);
            }
            return result;
        }
    
        @Override public JsonElement serialize(Multimap<String, ?> src, Type type, JsonSerializationContext context) {
            final Map<?, ?> map = src.asMap();
            return context.serialize(map);
        }
    
        private <V> Type multimapTypeToMapType(Type type) {
            final Type[] typeArguments = ((ParameterizedType) type).getActualTypeArguments();
            assert typeArguments.length == 2;
            @SuppressWarnings("unchecked")
            final TypeToken<Map<String, Collection<V>>> mapTypeToken = new TypeToken<Map<String, Collection<V>>>() {}
            .where(new TypeParameter<V>() {}, (TypeToken<V>) TypeToken.of(typeArguments[1]));
            return mapTypeToken.getType();
        }
    }
    

    包含测试的完整代码可以在here找到。

    【讨论】:

    • 愿意将适配器贡献给github.com/google-gson/typeadapters吗? (associated bug)
    • @dimo414 现在没时间,但请随意。我想,SO 许可证已经允许了。
    • 不依赖Guava有没有合理的方法来实现multimapTypeToMapType(Type type)方法?您能否添加实现(我知道,一厢情愿,但问也无妨)或描述如何管理它。
    • @GRosenberg 我看到我的链接已损坏,已修复。你确定,你需要一个不依赖 Guava 的 Guava 类的 Type 吗?
    • @maaartinus - 我有自己的非 Guava Multimap 类,具有特殊功能。希望与 Gson 一起使用而无需添加 Guava 作为依赖项。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-03
    • 1970-01-01
    • 2013-07-31
    • 2023-03-19
    • 2021-10-21
    • 2023-03-31
    • 1970-01-01
    相关资源
    最近更新 更多