7

キーの値がオブジェクトのリストであるマップがあります。キーをシリアル化することはできますbuilder.enableComplexMapKeySerialization();が、オブジェクトではなく逆シリアル化時に文字列を返すため、値は期待どおりにシリアル化されません。

以下はシリアル化の出力です

[{"id":31001、 "name":Teacher "]}、//これが鍵です

[{"id":33033、 "name": "student1"}、{"id":34001、 "name": "student2"}]]、//これは値のリストです

関連するTypeTokenを使用しましたがTypeToken<HashMap<Teacher, List<Student>>>、それでもリスト値は逆シリアル化時にオブジェクトではなく文字列を返します。

4

1 に答える 1

20

JSONは、名前と値のペアで構成されています(値側は物事のリストにすることができます)。その名前の部分は文字列です(http://json.orgを参照) 。

あなたがやろうとしているのは、名前としてオブジェクトを使用することです。直接それを行うことはできません。JSONオブジェクトを名前と値のペアの名前にすることはできません。

enableComplexMapKeySerializationのドキュメントを読むと、結果のJSONがどうなるかが説明されています。

生成されるJSON(JSON配列としてのマップ)は、完全に逆シリアル化されてマップに戻ります。以下は、完全な実例です(Java7)。

JSONからJavaに逆シリアル化したら、マップを反復処理してキーを取得していることに注意してください。これは、の新しいインスタンスを作成してそれをキーとして機能させる方法がないためequals()hashCode()オーバーライドされないためです(参照値のみが比較されます)。TeacherTeacher

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;


public class App 
{
    public static void main( String[] args )
    {
        HashMap<Teacher, List<Student>> map = new HashMap<>();
        Teacher t = new Teacher("12345", "Teacher");
        Teacher t2 = new Teacher("23456", "Teacher2");
        ArrayList<Student> list = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            list.add(new Student(String.valueOf(i), "Student" + String.valueOf(i)));
        }

        map.put(t, list);
        map.put(t2, list);

        GsonBuilder builder = new GsonBuilder();

        Gson gson =
            builder.enableComplexMapKeySerialization().setPrettyPrinting().create();
        Type type = new TypeToken<HashMap<Teacher,List<Student>>>(){}.getType();
        String json = gson.toJson(map, type);
        System.out.println(json);

        System.out.println("\nAfter deserialization:");
        HashMap<Teacher, List<Student>> map2 = gson.fromJson(json, type);

        for (Teacher t3 : map2.keySet()) {
            System.out.println(t3.name);
            for (Student s2 : map2.get(t3)) {
                System.out.println("\t" + s2.name);
            }
        }
    }
}

class Teacher {
    public String id;
    public String name;

    public Teacher(String id, String name) {
        this.id = id;
        this.name = name;
    }
}

class Student {
    public String id;
    public String name;

    public Student(String id, String name) {
        this.id = id;
        this.name = name;
    }

}

出力:

[
  [
    {
      "id": "12345",
      "name": "Teacher"
    },
    [
      {
        "id": "0",
        "name": "Student0"
      },
      {
        "id": "1",
        "name": "Student1"
      },
      {
        "id": "2",
        "name": "Student2"
      }
    ]
  ],
  [
    {
      "id": "23456",
      "name": "Teacher2"
    },
    [
      {
        "id": "0",
        "name": "Student0"
      },
      {
        "id": "1",
        "name": "Student1"
      },
      {
        "id": "2",
        "name": "Student2"
      }
    ]
  ]
]

After deserialization:
Teacher2
    Student0
    Student1
    Student2
Teacher
    Student0
    Student1
    Student2

を実装equals()hashCode()Teacherクラスに入れると、の新しいインスタンスを使用Teacherしてマップから物を取得できるようになります。

class Teacher {

    public String id;
    public String name;

    public Teacher(String id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public int hashCode()
    {
        int hash = 3;
        hash = 37 * hash + Objects.hashCode(this.id);
        hash = 37 * hash + Objects.hashCode(this.name);
        return hash;
    }

    @Override
    public boolean equals(Object obj)
    {
        if (obj == null)
        {
            return false;
        }
        if (getClass() != obj.getClass())
        {
            return false;
        }
        final Teacher other = (Teacher) obj;
        if (!Objects.equals(this.id, other.id))
        {
            return false;
        }
        if (!Objects.equals(this.name, other.name))
        {
            return false;
        }
        return true;
    }

}

それができたら、次のことができます。

...
HashMap<Teacher, List<Student>> map2 = gson.fromJson(json, type);
Teacher t = new Teacher("23456", "Teacher2");
List<Student> list = map2.get(t);
...
于 2013-02-03T21:35:54.227 に答える