gpt4 book ai didi

java - Gson 中的自定义 Java map 反序列化器

转载 作者:行者123 更新时间:2023-11-30 06:00:36 28 4
gpt4 key购买 nike

是否可以将对象对数组转换为Map ,通过从每对中选择值,而不创建中间 POJO?

例如,假设有 2 Java类( Key.classValue.class )和 JSON由其对象的序列化对构造的数组,如下

[
{"key":{}, "value":{}}, // Objects k1, v1
{"key":{}, "value":{}}, // Objects k2, v2
{"key":{}, "value":{}}, // Objects k3, v3
{"key":{}, "value":{}}, // Objects k4, v4
]

可以Gson “直接”(即,没有 POJO 定义)将上面的数组反序列化为 Map ,其中实际的键和值是通过相应的 Key 的操作来填充的和Value对象,而不是“完整”对象?

换句话说,给定两个 Java类型KV这可能与 Key 不同和Value ,每对的反序列化应该是

(k1:Key, v1:Value) --> (k1':K, v1':V)

哪里

k1' = function(k1)
v1' = function(v1)

像这样的自定义适配器不起作用:

GsonBuilder builder = new GsonBuilder();
Type type = (new TypeToken<Map<K, V>>() {}).getType();
builder.registerTypeAdapter(type, new JsonDeserializer<Map<Key, Value>>() {
@Override
public Map<K, V> deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
// Custom deserialization block,
// invoking the `function()` method
}
Gson gson = builder.create();

使用上述适配器会产生Gson将整个数组传递给deserialize()方法,必须手动操作,既繁琐又容易出错。

带有自定义POJO喜欢

public class KeyValue {
Key k;
Value v;
}

以上JSON数组可以反序列化为数组或 KeyValue 的集合对象,然后可以将其转换为 Map<K, V> 。但如果没有 KeyValue 也可以做到同样的事情吗? POJO;

最佳答案

如果你想避免使用被称为KeyValue的POJO类,我认为使用gson做到这一点的唯一方法是创建一个适配器。原因是您的 JSON 不符合任何通用的内置类,因此如果没有自定义逻辑,gson 将无法理解它。

由于您拥有 KeyValue 类,因此您可以在自定义适配器内部利用它们。我想你会发现这减少了代码的乏味。

public static void main(String[] args) throws IOException {
GsonBuilder builder = new GsonBuilder();
Type type = (new TypeToken<Map<Key, Value>>() {}).getType();
builder.registerTypeAdapter(type, new JsonDeserializer<Map<Key, Value>>() {
@Override
public Map<Key, Value> deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
Map<Key, Value> resultMap = new HashMap<>();
JsonArray jArr = json.getAsJsonArray();
for(int i=0; i < jArr.size(); i++){
JsonObject item = jArr.get(i).getAsJsonObject();
processKeyValue(item, resultMap);
}
return resultMap;
}

private void processKeyValue(JsonObject mapEntry, Map<Key, Value> resultMap){
Gson gson = new Gson();
Key key = gson.fromJson(mapEntry.get("key"), Key.class);
Value value = gson.fromJson(mapEntry.get("value"), Value.class);
resultMap.put(key, value);
}
});
Gson gson = builder.create();

//Note: assume that the variable "json" is a JSON string. I removed my code for getting the string since I'm just reading from a file and I don't know how you're getting your data.

// Deserialization

Map<Key,Value> outputMap = gson.fromJson(json, type);


System.out.println("RESULTS: "+outputMap.toString());
}

我使用了您的示例数据,但稍加修改以包含更多内容。我为 KeyValue 创建了两个非常简单的 POJO 类 - 它们只有一个名为 idString 字段,一个该字段的 getter 和 setter,以及一个 toString 方法。

这是我运行上述代码时使用的输入:

[
{"key":{"id":"k1"}, "value":{"id":"v1"}},
{"key":{"id":"k2"}, "value":{"id":"v2"}},
{"key":{"id":"k3"}, "value":{"id":"v3"}},
{"key":{"id":"k4"}, "value":{"id":"v4"}}
]

输出为:

RESULTS: {Key [id=k2]=Value [id=v2], Key [id=k1]=Value [id=v1], Key [id=k3]=Value [id=v3], Key [id=k4]=Value [id=v4]}

关于java - Gson 中的自定义 Java map 反序列化器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52340287/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com