fromjson json hashmap gson

fromjson - gson java



Obteniendo stackoverflowerror de Gson al convertir hashmap en objeto JSON (1)

No incluyó su definición de clase Node , pero supongo que se parece a esto:

public class Node { public final String id; public Node parent; public final ArrayList<Node> children = new ArrayList<>(); public Node(String id) { this.id = id; } }

Esta es una excelente forma de representar una estructura de datos de árbol en la memoria (ignorando algunos problemas de estilo no relacionados como el uso de campos públicos), pero es imposible serializarla. ¿Por qué? Como cualquier Node con un elemento parent no nulo tiene una relación cíclica, un elemento secundario contiene una referencia a su elemento principal, que a su vez contiene una referencia al elemento secundario, que a su vez contiene una referencia al elemento primario, que a su vez contiene ... ..

De la guía del usuario :

Tenga en cuenta que no puede serializar objetos con referencias circulares ya que eso dará como resultado una recursión infinita.

Podemos desencadenar el mismo error con este ejemplo más simple:

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

Entonces, ¿cómo podemos arreglar esto? Depende del comportamiento que desee. Una opción fácil es evitar que Gson intente serializar el campo parent (no lo necesitamos, ya que podemos reconstruirlo desde la lista de children ). Para hacer esto, simplemente marque parent como transient y Gson no lo incluirá en el resultado. De manera similar, puede hacer que los children el campo transient si la grabación explícita de la relación principal es más útil. Sin embargo, una ventaja de serializar el campo de children es que puede pasar el nodo raíz y se recorrerá todo el árbol.

Otra opción es serializar una estructura de datos diferente a Map<String, Node> : actualmente está asignando cada ID de nodo a su objeto Node (que, transitivamente, contiene una referencia a cada otro nodo), lo que significa que incluso si repara el relación cíclica, todavía obtendrás un JSON extraño como resultado. Parece que lo que realmente quieres es serializar las relaciones ID -> parent o ID -> children, que serían una estructura de datos Map<String, String> o Map<String, List<String>> que Gson no tiene problemas para serializar. Si esa es la estructura que desea, simplemente podría atravesar su árbol y construir tal estructura de datos primero, o definir un deserializador personalizado que convierta un Node en la estructura JSON exacta que desee.

Quiero representar los datos en la estructura de árbol como objeto java y luego quiero convertirlo a objeto JSON.

Con la ayuda de las entradas de stackoverflow:

Convertir java arrayList de la relación padre / hijo en el árbol?

hashmap a JSON usando GSON

Tenía abajo la función principal y la lista de "pares" contiene un par: hijo y padre

ArrayList<Pair> list= new ArrayList<>(); list.add(new Pair("6", "4")); list.add(new Pair("5", "4")); list.add(new Pair("4", "3")); list.add(new Pair("2", "3")); list.add(new Pair("3", "null")); Map<String, Node> o_map= new HashMap<>(); for (Pair l: list) { Node parent = o_map.getOrDefault(l.getParentId(), new Node(l.getParentId())); Node child = o_map.getOrDefault(l.getChildId(), new Node(l.getChildId())); parent.children.add(child); child.parent = parent; o_map.put(parent.id, parent); o_map.put(child.id, child); } Gson gs = new Gson(); System.out.println(gs.toJson(o_map)); }

Sin embargo, este código regresa:

Exception in thread "main" java.lang.StackOverflowError at java.io.StringWriter.write(StringWriter.java:112) at com.google.gson.stream.JsonWriter.string(JsonWriter.java:576) at com.google.gson.stream.JsonWriter.writeDeferredName(JsonWriter.java:402) at com.google.gson.stream.JsonWriter.beginArray(JsonWriter.java:287) at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:95) at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:61) at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:112) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:239) at com.google.gson.Gson$FutureTypeAdapter.write(Gson.java:968)

error.

No entiendo por qué devuelve ese error. ¿Cuál podría ser la razón? Muchas gracias por adelantado.