将Guava HashMultimap转换为json

时间:2014-09-04 19:57:15

标签: json gson guava multimap

我想将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)

2 个答案:

答案 0 :(得分:13)

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

在您的示例中,生成的地图的类型为Map<String, Collection<Object>>。 Gson应该能够正确地序列化。

答案 1 :(得分:5)

您需要撰写JsonAdapterJsonDeserializerJsonSerializer。它相当可怕,但我想尝试一下。

基本上,您将所有内容委托给Map<String, Collection<V>>

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