我有一个扩展TreeSet
类的类。其构造函数为TreeSet
提供了自定义比较器:
public class SortedPersonSet extends TreeSet<Person> {
public SortedPersonSet(Comparator<Person> comp) {
super(comp);
}
}
例如,我想使用GSON
对该类进行序列化和反序列化:
SortedPersonSet personSet =
new SortedPersonSet((p1, p2) -> Long.compare(p1.getAge(), p2.getAge()));
personSet.add(new Person("Peter", 21));
personSet.add(new Person("Klaus", 17));
personSet.add(new Person("Martin", 27));
personSet.add(new Person("John", 22));
// Serialize
Gson gson = new GsonBuilder().create();
String personSetAsString = gson.toJson(personSet);
System.out.println(personSetAsString);
// Deserialize
Gson gsonb = new GsonBuilder().create();
SortedPersonSet newPersons = gsonb.fromJson(personSetAsString, SortedPersonSet.class);
System.out.println(newPersons);
但是,此版本引发异常,因为类Person
没有实现Comparable
。
因此,我尝试了通过实现自定义JsonDeserializer
并返回自定义比较器的SortedPersonSet
来帮助here的方法:
public class SortedSetDeserializer implements JsonDeserializer<SortedPersonSet> {
@Override
public SortedPersonSet deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
return new SortedPersonSet((p1, p2) -> Long.compare(p1.getAge(), p2.getAge()));
}
}
// Deserialization in main
Gson gsonb = new GsonBuilder()
.registerTypeAdapter(SortedPersonSet.class, new SortedSetDeserializer()).create();
SortedPersonSet newPersons = gsonb.fromJson(personSetAsString, SortedPersonSet.class);
System.out.println(newPersons);
不幸的是,我的代码中仍然存在错误,因为当我通过SortedPersonSet newPersons = gsonb.fromJson(personSetAsString, SortedPersonSet.class);
反序列化JSON字符串时,结果SortedPersonSet
为空。希望您能指出我犯错的地方。另一个(希望更简单)的选项也将受到赞赏。
谢谢!
答案 0 :(得分:1)
结果集为空,因为在自定义反序列化器中,您不解析数组;仅创建新集合并返回它。具有实际反序列化类的简单实现应如下所示:
class SortedSetDeserializer implements JsonDeserializer<SortedPersonSet> {
@Override
public SortedPersonSet deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
SortedPersonSet people = new SortedPersonSet(Comparator.comparingLong(Person::getAge));
if (json.isJsonArray()) {
JsonArray array = json.getAsJsonArray();
array.forEach(e -> {
people.add(context.deserialize(e, Person.class));
});
}
return people;
}
}
另一方面,创建TreeSet
的新子类型听起来不太好。如果您的Person
类将实现Comparable
:
class Person implements Comparable<Person> {
@Override
public int compareTo(Person o) {
return Long.compare(this.getAge(), o.getAge());
}
}
您可以轻松地将此数组反序列化为TreeSet
:
Type type = new TypeToken<TreeSet<Person>>() {
}.getType();
TreeSet<Person> newPersons = gsonb.fromJson(personSetAsString, type);