我正在使用Gson和Guava。我有一个我要序列化的类,看起来像这样sscce
import com.google.common.collect.Multimap;
public class FooManager {
private Multimap<String, Foo> managedFoos;
// other stuff
}
Gson不知道如何序列化。所以我这样做了:
public final class FoomapSerializer implements
JsonSerializer<Multimap<String, Foo>> {
@SuppressWarnings("serial")
private static final Type t =
new TypeToken<Map<String, Collection<Foo>>>() {}.getType();
@Override
public JsonElement serialize(Multimap<String, Foo> arg0, Type arg1,
JsonSerializationContext arg2) {
return arg2.serialize(arg0.asMap(), t);
}
}
但是,我担心一遍又一遍地调用.asMap()
会很慢,即使基础Map
很少改变。 (Foo
对象的序列化将经常更改,但映射本身不会在初始化之后)。还有更好的方法吗?
答案 0 :(得分:7)
Multimap.asMap在O(1)时间内返回Multimap的缓存视图。这不是一项昂贵的操作。 (事实上,它非常便宜,最多需要一次分配。)
答案 1 :(得分:3)
以下是使用Guava TypeToken
的多图的通用序列化程序示例。如果您愿意,可以执行此操作的一些变体,例如为每个需要序列化的多图类型创建序列化程序的实例,这样您只需为每个类型解析一次asMap()
的返回类型。
public enum MultimapSerializer implements JsonSerializer<Multimap<?, ?>> {
INSTANCE;
private static final Type asMapReturnType = getAsMapMethod()
.getGenericReturnType();
@Override
public JsonElement serialize(Multimap<?, ?> multimap, Type multimapType,
JsonSerializationContext context) {
return context.serialize(multimap.asMap(), asMapType(multimapType));
}
private static Type asMapType(Type multimapType) {
return TypeToken.of(multimapType).resolveType(asMapReturnType).getType();
}
private static Method getAsMapMethod() {
try {
return Multimap.class.getDeclaredMethod("asMap");
} catch (NoSuchMethodException e) {
throw new AssertionError(e);
}
}
}