Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 413
durron597 Avatar asked Dec 28 '25 03:12

durron597


2 Answers

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.)

like image 177
Louis Wasserman Avatar answered Dec 30 '25 17:12

Louis Wasserman


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);
    }
  }
}
like image 36
ColinD Avatar answered Dec 30 '25 15:12

ColinD



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!