我正在尝试使用GSon序列化树。这是我要序列化的TreeNode
的类:
public class TreeNode {
private TreeNode parent;
private ArrayList<TreeNode> children;
private Object value;
//methods
}
我的GSon电话看起来像这样:
TreeNode headNode = getHeadNode();
Gson gson = new Gson();
Type typeOfSrc = new TypeToken<TreeNode>(){}.getType();
String gsonTreeString = gson.toJson(headNode,typeOfSrc);
一旦headNode
至少有一个孩子,就会发生堆栈溢出,我不明白为什么。有人能告诉我我做错了吗?
答案 0 :(得分:1)
成员父指向其父级,其父级指向一个子级,该子级的父级指向父级...
答案 1 :(得分:1)
Will是对的,问题是,存在无限的保存路径。您可以通过不保存父级来解决此问题。您可以在从JSON对象读取时设置父级。为避免保存父级,只需将其设置为瞬态。
public class TreeNode {
private transient TreeNode parent;
private ArrayList<TreeNode> children;
private Object value;
//methods
}
转换回POJO时,请调用下面的setParent-method。
TreeNode newRoot = gson.fromJson(treeJson, TreeNode.class);
setParents(newRoot);
setParents-method只遍历节点的所有子节点,并将其父节点设置为节点为子节点的节点。
private void setParents(TreeNode root) {
for (TreeNode node : root.getChildren()) {
node.setParent(root);
setParents(node);
}
}
答案 2 :(得分:0)
在Gson中,您可以创建一个自定义适配器来序列化表示树的数据结构。您要序列化节点及其所有子节点。这样做的技巧是递归调用write
方法以填充JsonWriter
。以下代码适用于您的示例:
public class TreeNodeAdapter extends TypeAdapter<TreeNode> {
@Override
public void write(JsonWriter jsonWriter, TreeNode node) throws IOException {
jsonWriter.beginObject()
.name("coordinates")
.jsonValue("\"" + node.getValue + "\"")
.name("children")
.beginArray();
// Recursive call to the children nodes
for (Node c : node.getChildren()) {
this.write(jsonWriter, c);
}
jsonWriter.endArray()
.endObject();
}
@Override
public Node read(JsonReader jsonReader) throws IOException {
return null;
}
}
然后,要使用TreeNodeAdapter
仅使NodeTree
无效,并在自定义适配器中使用GsonBuilder
来序列化对象。
NodeTree tree = new NodeTree(...);
NodeAdapter nodeAdapter = new NodeAdapter();
GsonBuilder gsonBuilder = new GsonBuilder().registerTypeAdapter(NodeTree.class, nodeAdapter);
Gson gson = gsonBuilder.create();
gson.toJson(tree); // JSON string