I want to print HashMultiMap as json.
HashMultimap<String,Object> multimap = HashMultimap.create();
multimap.put("a",Obj1);
multimap.put("a",Obj3);
multimap.put("b",Obj2);
to
{
"a":[Obj1,Obj3],
"b":[Obj2]
}
Obj1 and other objects should again be in json(to keep it clean, I have shown it as objects)
I can iterate over the individual keys and convert set of Objects to json using libraries such as Gson.
But to get the entire snapshot of the HashMultimap, I want to convert it to json and inspect it.
Gson could not convert the entire map, but could do individual values(list of objects to json)
Call asMap()
on the MultiMap first. This converts the MultiMap to a standard Map where each value is a Collection.
In your example, the type of the resulting Map is Map<String, Collection<Object>>
. Gson should be able to serialise this correctly.
You need to write a JsonAdapter
or both JsonDeserializer
and JsonSerializer
. It's rather terrible, but I wanted to try.
Basically, you delegate everything to a 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();
}
}
The full code including a test can be found here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With