简体   繁体   English

使用 GSON 使用自定义比较器反序列化扩展 TreeSet 的类

[英]Deserialize class extending TreeSet with custom comparator using GSON

I have a class which extends the TreeSet class.我有一个扩展TreeSet类的类。 Its constructor provides a custom comparator to the TreeSet :它的构造函数为TreeSet提供了一个自定义比较器:

public class SortedPersonSet extends TreeSet<Person> {
    public SortedPersonSet(Comparator<Person> comp) {
        super(comp);
    }
}

I want to serialize and deserialize that class using GSON for example:我想使用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);

However, this version throws an exception because class Person does not implement Comparable .然而,这个版本会抛出一个异常,因为类Person没有实现Comparable

So I have tried the approach which helped here by implementing a custom JsonDeserializer which returns a SortedPersonSet with a custom comparator:所以我尝试了通过实现自定义JsonDeserializer来帮助这里的方法,该方法返回带有自定义比较器的SortedPersonSet

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

Unfortunately, there is still a mistake in my code, because when I deserialize the JSON string via SortedPersonSet newPersons = gsonb.fromJson(personSetAsString, SortedPersonSet.class);不幸的是,我的代码中仍然存在错误,因为当我通过SortedPersonSet newPersons = gsonb.fromJson(personSetAsString, SortedPersonSet.class);反序列化 JSON 字符串时SortedPersonSet newPersons = gsonb.fromJson(personSetAsString, SortedPersonSet.class); , the resulting SortedPersonSet is empty. ,结果SortedPersonSet为空。 I hope you can point out where I made the mistake.我希望你能指出我哪里出错了。 Another (hopefully simpler) option would be appreciated as well.另一个(希望更简单)选项也将受到赞赏。

Thanks in advance!提前致谢!

Result set is empty because in custom deserialiser you do not parse array;结果集为空,因为在自定义反序列化器中您不解析数组; only creates new set and returns it.只创建新集合并返回它。 Simple implementation with real deserialising class should look like this:使用真正的反序列化类的简单实现应该如下所示:

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;
    }
}

From other side, creating new subtype of TreeSet does not sound good.另一方面,创建TreeSet新子类型听起来并不好。 If your Person class will implement Comparable :如果您的Person类将实现Comparable

class Person implements Comparable<Person> {

    @Override
    public int compareTo(Person o) {
        return Long.compare(this.getAge(), o.getAge());
    }
}

You can easily deserialise this array to TreeSet :您可以轻松地将此数组反序列化为TreeSet

Type type = new TypeToken<TreeSet<Person>>() {
}.getType();
TreeSet<Person> newPersons = gsonb.fromJson(personSetAsString, type);

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

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