簡體   English   中英

使用 GSON 使用自定義比較器反序列化擴展 TreeSet 的類

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

我有一個擴展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

 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 newPersons = gsonb.fromJson(personSetAsString, SortedPersonSet.class); ,結果SortedPersonSet為空。 我希望你能指出我哪里出錯了。 另一個(希望更簡單)選項也將受到贊賞。

提前致謝!

結果集為空,因為在自定義反序列化器中您不解析數組; 只創建新集合並返回它。 使用真正的反序列化類的簡單實現應該如下所示:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM