I want to represent data in tree structure as java object then I want to convert it to JSON object.
With the help of stackoverflow entries:
Convert java arr
You didn't include your Node
class definition, but I'm guessing it looks something like this:
public class Node {
public final String id;
public Node parent;
public final ArrayList<Node> children = new ArrayList<>();
public Node(String id) {
this.id = id;
}
}
This is a fine way to represent a tree data structure in memory (ignoring some unrelated style issues like using public fields), but it's impossible to serialize. Why? Because any Node
with a non-null parent
has a cyclical relationship - a child contains a reference to its parent, which in turn contains a reference to the child, which in turn contains a reference to the parent, which in turn contains .....
From the user guide:
Note that you can not serialize objects with circular references since that will result in infinite recursion.
We can trigger the same error with this simpler example:
Node root = new Node("A");
Node child = new Node("B");
root.children.add(child);
child.parent = root;
System.out.println(new Gson().toJson(root)); // passing in child would similarly fail
So how can we fix this? It depends on what behavior you want. One easy option is to prevent Gson from attempting to serialize the parent
field (we don't need it, as we can reconstruct it from the children
list). To do this just mark parent as transient and Gson will not include it in the result. You could similarly make children
the transient
field if explicitly recording the parent relationship is more helpful. A benefit of serializing the children
field however is that you can just pass in the root node and the whole tree will be traversed.
Another option is to serialize a different data structure than Map<String, Node>
- you're currently mapping each node ID to its Node
object (which, transitively, contains a reference to every other node), meaning that even if you fix the cyclical relationship you're still going to get some odd JSON as a result. It seems like what you'd really want is to just serialize the ID -> parent or ID -> children relationships, which would be a Map<String, String>
or Map<String, List<String>>
data structure which Gson will have no trouble serializing. If that's the structure you want you could simply traverse your tree and construct such a data structure first, or define a custom deserializer which converts a Node
into the exact JSON structure you want.