简体   繁体   English

如何在番石榴表中使用 Gson

[英]How to use Gson with guava tables

I'm storing my data in a Guava Table , and need it to save to a JSON file .我将数据存储在 Guava Table ,需要将其保存到JSON 文件中

I managed to get that working with the Gson#toJson method just fine, but I'm having difficulties reading it back into the table.我设法使用Gson#toJson方法Gson#toJson很好地工作,但是我很难将它读回表格中。

Does anyone know what I could do?有谁知道我能做什么?

You should write your own set of Serializer / Deserializer s or even TypeAdapter(Factory) .您应该编写自己的一组Serializer / Deserializer甚至TypeAdapter(Factory) Here's a sample implementation based on https://github.com/acebaggins/guava-gson-serializers :这是基于https://github.com/acebaggins/guava-gson-serializers的示例实现:

static class TableSerializer implements JsonSerializer<Table> {

    @Override
    public JsonElement serialize(Table table, Type type, JsonSerializationContext context) {
        return context.serialize(table.rowMap());
    }
}

static class TableDeserializer implements JsonDeserializer<Table<?, ?, ?>> {

    @Override
    public Table deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
        Type[] typeArguments = ((ParameterizedType) type).getActualTypeArguments();
        Type parameterizedType = hashMapOf(
                typeArguments[0],
                hashMapOf(typeArguments[1], typeArguments[2]).getType()).getType();
        Map<?, Map<?, ?>> map = context.deserialize(json, parameterizedType);

        Table<Object, Object, Object> table = HashBasedTable.create();
        for (Object rowKey : map.keySet()) {
            Map<?, ?> rowMap = map.get(rowKey);
            for (Object columnKey : rowMap.keySet()) {
                Object value = rowMap.get(columnKey);
                table.put(rowKey, columnKey, value);
            }
        }
        return table;
    }
}

// see https://github.com/acebaggins/guava-gson-serializers/blob/master/src/main/java/com/baggonius/gson/immutable/Types.java
static <K, V> TypeToken<HashMap<K, V>> hashMapOf(Type key, Type value) {
    TypeParameter<K> newKeyTypeParameter = new TypeParameter<K>() {};
    TypeParameter<V> newValueTypeParameter = new TypeParameter<V>() {};
    return new TypeToken<HashMap<K, V>>() {}
            .where(newKeyTypeParameter, typeTokenOf(key))
            .where(newValueTypeParameter, typeTokenOf(value));
}

private static <E> TypeToken<E> typeTokenOf(Type type) {
    return (TypeToken<E>) TypeToken.of(type);
}

which should be used like this:应该像这样使用:

@Test
public void shouldSerializeAndDeserializeGuavaTable() {
    Table<Integer, Integer, String> table = ImmutableTable.<Integer, Integer, String>builder()
            .put(1, 1, "eleven")
            .put(1, 0, "ten")
            .put(4, 2, "forty-two")
            .build();

    Gson gson = new GsonBuilder()
            .registerTypeHierarchyAdapter(Table.class, new TableSerializer())
            .registerTypeHierarchyAdapter(Table.class, new TableDeserializer())
            .create();
    String tableAsString = gson.toJson(table); // {"1":{"1":"eleven","0":"ten"},"4":{"2":"forty-two"}}

    Table<Integer, Integer, String> deserializedTable = gson.fromJson( // {1={0=ten, 1=eleven}, 4={2=forty-two}}
            tableAsString,
            new TypeToken<Table<Integer, Integer, String>>() {}.getType());

    Assertions.assertThat(deserializedTable)
            .hasSize(3)
            .containsCell(1, 1, "eleven")
            .containsCell(1, 0, "ten")
            .containsCell(4, 2, "forty-two");
}

If I find some spare time, I might create a PR to https://github.com/acebaggins/guava-gson-serializers with properly tested changes for Table (de)serialization.如果我找到一些空闲时间,我可能会创建一个 PR 到https://github.com/acebaggins/guava-gson-serializers并正确测试表(反)序列化的更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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