将Guava HashMultimap转换为json
我想将HashMultiMap打印为json将Guava HashMultimap转换为json,json,gson,guava,multimap,Json,Gson,Guava,Multimap,我想将HashMultiMap打印为json HashMultimap<String,Object> multimap = HashMultimap.create(); multimap.put("a",Obj1); multimap.put("a",Obj3); multimap.put("b",Obj2); Obj1和其他对象也应该是json格式的(为了保持干净,我将其显示为对象) 我可以迭代各个键,并使用诸如Gson之类的库将对象集转换为json 但是为了获得HashMult
HashMultimap<String,Object> multimap = HashMultimap.create();
multimap.put("a",Obj1);
multimap.put("a",Obj3);
multimap.put("b",Obj2);
Obj1和其他对象也应该是json格式的(为了保持干净,我将其显示为对象)我可以迭代各个键,并使用诸如Gson之类的库将对象集转换为json 但是为了获得HashMultimap的整个快照,我想将其转换为json并对其进行检查
Gson无法转换整个映射,但可以执行单个值(将对象列表转换为json)您需要编写一个
JsonAdapter
或同时编写JsonDeserializer
和JsonSerializer
。这很糟糕,但我想试试
基本上,您可以将所有内容委托给映射
静态类MultimapAdapter实现JsonDeserializer、JsonSerializer{
@重写公共多重映射反序列化(JsonElement json,类型,
JsonDeserializationContext)抛出JsonParseException{
最终HashMultimap结果=HashMultimap.create();
最终映射值=(集合)e.getValue();
result.putAll(e.getKey(),value);
}
返回结果;
}
@重写公共JsonElement序列化(多映射src,类型,JsonSerializationContext){
final Map=src.asMap();
返回context.serialize(映射);
}
私有类型multimapTypeToMapType(类型){
最终类型[]类型参数=((ParameteredType)类型)。getActualTypeArguments();
断言typeArguments.length==2;
@抑制警告(“未选中”)
final TypeToken mapTypeToken=新的TypeToken(){}
.where(new TypeParameter(){},(TypeToken)TypeToken.of(typeArguments[1]);
返回mapTypeToken.getType();
}
}
可以找到包含测试的完整代码。首先调用MultiMap。这会将多重映射转换为标准映射,其中每个值都是一个集合
在您的示例中,结果映射的类型是
Map
。Gson应该能够正确地序列化它。是的,在发布问题后检查了此API:)。感谢您指出它。@sat当您使用适配器时,这一切都会自动发生。是否将适配器贡献给?()@dimo414现在没时间了,但请随意。我想,SO许可证已经允许了。有没有合理的方法来实现multimapTypeToMapType(Type Type)
方法而不依赖于Guava?你能添加实现(我知道,一厢情愿,但不问也无妨)或描述如何管理它。@GRosenberg我看到我的链接断了,修复了。你确定,你需要一个番石榴类的类型
,而不依赖番石榴?@maaartinus-我有自己的非番石榴多图类,具有特殊功能。希望与Gson一起使用,而不必添加番石榴作为依赖项。
{
"a":[Obj1,Obj3],
"b":[Obj2]
}
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();
}
}