編輯:它看起來像在這種情況下,有一個更容易的解決這個問題,即通過註冊多集的instance creator方式:
private static class MultisetInstanceCreator implements InstanceCreator<Multiset<?>> {
@Override
public Multiset<?> createInstance(Type type) {
return HashMultiset.create();
}
}
Gson gson = new GsonBuilder()
.registerTypeAdapter(Multiset.class, new MultisetInstanceCreator())
.create();
的實例創建者只定義一個多重應該如何創建,因爲Guava集合沒有默認的構造函數(無論如何,Multiset都是接口)。
原來的答覆:我不知道這是否是達到你想要什麼是最好的或最簡單的方法,但它是最近對我們工作了一個類似的問題的一種方法(在我們的情況下,它是deserialising到一個ImmutableMap)。
其基本思想是註冊一個custom deserialiser,它基本上做了你已經發現的一個可能的解決方案:將數據反序列化到一個ArrayList,然後把它變成一個Multiset。這樣做的好處是你只需要註冊一次自定義的反序列化器,而不必到處都知道首先使用ArrayList類型。
這種定製解串器看起來是這樣的:
private static class MultisetDeserializer implements JsonDeserializer<Multiset<?>> {
@Override
public Multiset<?> deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
ParameterizedType parameterizedType = (ParameterizedType) type;
Type[] typeArguments = parameterizedType.getActualTypeArguments();
ParameterizedType listType = new ListParameterizedType(typeArguments);
List<?> list = context.deserialize(json, listType);
return HashMultiset.create(list);
}
}
總之,這蒙上預期的類型deserialise到(例如,在你的情況new TypeToken<Multiset<String>>(){}.getType()
),以ParameterizedType
的類型參數(在你的例子字符串),以獲得。然後它創建一個新的ParameterizedType,它是具有相同類型參數的ArrayList類型(如下所示)。使用上下文將JSON反序列化爲這種新類型之後,您只需致電HashMultiset.create
即可。
的ListParameterizedType
看起來是這樣的:
private static class ListParameterizedType implements ParameterizedType {
private final Type[] typeArguments;
private ListParameterizedType(Type[] typeArguments) {
this.typeArguments = typeArguments;
}
@Override
public Type[] getActualTypeArguments() {
return typeArguments;
}
@Override
public Type getRawType() {
return ArrayList.class;
}
@Override
public Type getOwnerType() {
return null;
}
}
請注意,您可以用幾乎這裏的任何列表類取代ArrayList
,只要它有一個類型參數的默認的構造。
也可能有更簡單的方法來實現同樣的事情,例如,您可以通過檢查JsonElement
的方法(如isJsonArray()
)手動執行一些解析。這可以幫助您避免創建一個ArrayList,之後立即拋棄它。
這實際上就是我所做的(雖然代碼不夠整齊)。 –
@ChthonicProject查看我的更新答案,事實證明這比我想象的要容易得多,因爲你需要做的就是定義如何創建一個Multiset。 – andersschuller