我希望gson和de-gson使用泛型的hashmap
当我的密钥是字符串时,我可以成功地完成它,但如果它是一个字符串则不能
对象。
我在这里有两个代码部分。第一个不起作用,第二个起作用
确实。
// doesnt work works
try {
TradableBean tradable = new TradableBean("Tradable");
PositionBean position = new PositionBean(tradable);
Map<TradableBean, PositionBean> map1 = new HashMap<TradableBean, PositionBean>();
map1.put(tradable, position);
String json1 = gson.toJson(map1);
Map<TradableBean, PositionBean> map2 = gson.fromJson(json1, new TypeToken<Map<TradableBean, PositionBean>>(){}.getType());
System.out.println(map2);
} catch (Exception e) {
System.out.println("failed");
}
现在是工作部分 -
// works - with string
try {
String tradable = new String("Tradable");
PositionBean position = new PositionBean(new TradableBean("Tradable"));
Map<String, PositionBean> map1 = new HashMap<String,PositionBean>();
map1.put(tradable, position);
String json1 = gson.toJson(map1);
Map<String, PositionBean> map2 = gson.fromJson(json1, new TypeToken<Map<String, PositionBean>>() {}.getType());
System.out.println(map2);
} catch (Exception e) {
System.out.println("failed");
}
在TradableBean中我有:
@Override public int hashCode() {
return getId();}
@Override public boolean equals(Object obj) {
boolean equals = false;
if (obj instanceof AccountBean){
TradableBean tradable_p = (TradableBean)obj;
if (getId()==tradable_p.getId()){
equals = true;
}
}
return equals;
}
例外:
com.google.gson.JsonParseException: Expecting object found: "TradableBean{id=0, tradableName='Tradable', moneyMultiplier=1, expirationDate=null}" at com.google.gson.JsonObjectDeserializationVisitor.visitFieldUsingCustomHandler(JsonObjectDeserializationVisitor.java: 100) at com.google.gson.ObjectNavigator.navigateClassFields(ObjectNavigator.java: 150) at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:123) at com.google.gson.JsonDeserializationContextDefault.fromJsonPrimitive(JsonDeserializationContextDefault.java: 84) at com.google.gson.JsonDeserializationContextDefault.deserialize(JsonDeserializationContextDefault.java: 53) at com.google.gson.DefaultTypeAdapters $MapTypeAdapter.deserialize(DefaultTypeAdapters.java:531) at com.google.gson.DefaultTypeAdapters $MapTypeAdapter.deserialize(DefaultTypeAdapters.java:498) at com.google.gson.JsonDeserializerExceptionWrapper.deserialize(JsonDeserializerExceptionWrapper.java: 50)
答案 0 :(得分:2)
Gson限制你正在考虑它当前如何序列化地图键:通过调用toString()
。来自MapTypeAdapter
:
map.add(String.valueOf(entry.getKey()), valueElement);
MapTypeAdapter
文档中也描述了此行为。
这种实现实际上只适用于简单的原始类型作为映射键。如果键不是简单的原语,那么该对象是{@code toString} ed并且该值用作其键。
如果您坚持使用自定义类型作为地图密钥,那么我可以告诉您将要编写自定义序列化程序和/或自定义反序列化程序和/或生成字符串的toString()
表示很容易反序列化。
另外,请查看MapAsArrayTypeAdapter一种方法。 (它可用于调用GsonBuilder.enableComplexMapKeySerialization()
,而不是通过文档描述的直接实例化(因为它当前不是公共类)。我没有测试它以查看它的实现是否有效,但看起来很有希望。)
答案 1 :(得分:1)
我认为你需要自己编写custom serializator。
更新:告诉是例外:
com.google.gson.JsonParseException: Expecting object found: "TradableBean{id=0, tradableName='Tradable', moneyMultiplier=1, expirationDate=null}"
前置字符串“TradableBean”似乎是由使用某种toString()
的序列化编写的。反序列化期望{id=0,... }