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);
    }
  }
}
Другие вопросы по тегам