3

我同时使用 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对象的序列化会经常改变,但映射本身在初始化后不会改变)。有没有更好的办法?

4

2 回答 2

7

Multimap.asMap 在 O(1) 时间内返回 Multimap 的缓存视图。这不是一项昂贵的手术。(事实上​​,它非常便宜,最多需要一次分配。)

于 2013-06-24T16:47:21.803 回答
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);
    }
  }
}
于 2013-06-25T14:35:02.437 回答