Multimap и производительность gson
Я использую как Gson, так и Guava. У меня есть класс, который я хочу сериализовать, что-то вроде этого SSCCE
import com.google.common.collect.Multimap;
public class FooManager {
private Multimap<String, Foo> managedFoos;
// other stuff
}
Гсон не знает, как это сериализовать. Итак, я сделал это:
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
объекты будут часто меняться, но само сопоставление не меняется после инициализации). Есть ли способ лучше?
2 ответа
Multimap.asMap возвращает кэшированное представление Multimap за O(1) раз. Это не дорогая операция. (На самом деле, это довольно дешево, требует не более одного распределения.)
Вот пример универсального сериализатора для мультикарт с использованием 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);
}
}
}