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) 時間で返します。高価な操作ではありません。(実際のところ、これは非常に安価であり、多くても 1 つの割り当てしか必要としません。)

于 2013-06-24T16:47:21.803 に答える
3

これは、Guava のTypeToken. シリアライズする必要があるマルチマップ タイプごとにシリアライザーのインスタンスを作成するなど、必要に応じて実行できるいくつかのバリエーションがあり、それぞれに対してasMap()1 回の戻り値のタイプを解決するだけで済みます。

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 に答える