简体   繁体   中英

Multimap and gson performance

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM