I am using both Gson and Guava. I have a class that I want to serialize that looks like something like this sscce

import com.google.common.collect.Multimap;
public class FooManager {
  private Multimap<String, Foo> managedFoos;
  // other stuff
}

Gson doesn't know how to serialize that. So I did this:

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);
  }
}

However, I'm afraid calling .asMap() over and over again will be slow, even if the underlying Map rarely changes. (The serializations of the Foo objects will change often, but the mapping itself does not after initialization). Is there a better way?

有帮助吗?

解决方案

Multimap.asMap returns a cached view of the Multimap in O(1) time. It is not an expensive operation. (In point of fact, it's quite cheap, requiring at most one allocation.)

其他提示

Here's an example of a generic serializer for multimaps using Guava's TypeToken. There are some variations on this you could do if you wanted, like creating instances of the serializer for each multimap type you need to serialize so you only have to resolve the return type of asMap() once for each.

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);
    }
  }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top