Json Multiset vs ArrayList

I have objects Multiset<String>that I serialize as Json. I do this using Gson as follows:

Multiset<String> mset = ... ;
Gson gson = new Gson();
Files.write(Gson.toJson(mset), new File(abosulte_path_string), Charset.defaultCharset());

When I try to deserialize it, I do the following:

String json_string = ... // read from file
Type type = new TypeToken<Multiset<String>>(){}.getType();
Multiset<String> treated = gson.fromJson(json_string, type);

I get this error:

java.lang.ClassCastException: java.util.ArrayList cannot be cast to com.google.common.collect.Multiset

When I opened the json file, I see that the object is Multiset<String>really represented as an ArrayList ([string1, string2, ...]), with repetitions for the lines that were count > 1in the multiset.

I can of course pass it to an ArrayList and then use the constructor create(Iterable<>)to get my multiset, but it seems to be a roundabout way. Is there a more direct way to deserialize a json object to retrieve my multisets?

+3
source share
1 answer

EDIT: , , , :

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

, Multiset, Guava ( Multiset - ).

: , , , , ( ImmutableMap).

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

, , (, 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, .

+3

All Articles