I am using Java and GSON. I have a json array like this:
[{"ID":1001,
"name":"Egnatia-3isSeptembriou/Anatolika",
"latitude":40.626216,
"longitude":22.959864,
"Edge":[
{"destination_id":1030,"weight":6},
{"destination_id":1012,"weight":12}]
},
{
"ID":1002,
"name":"Egnatia-3isSeptembriou/Boreia",
"latitude":40.626055,
"longitude":22.959845,
"Edge":[
{"destination_id":1025,"weight":3},
{"destination_id":1008,"weight":5}]
}]
I would like to use GSON to make two classes such as:
public class Node {
int ID;
String name;
double latitude, longitude;
int previous = 0;
boolean visited = false;
double distance = Double.MAX_VALUE;
Edge[] Edge;
}
public class Edge {
Node destinationNode;
double weight;
}
Is there an elegant way to do that instead of copying all Nodes variables in Edge every time?
Thanks!
If relation between classes would be simple as aggregation where you always link from child to a parent you could write custom deserialiser. Like in this question: Reference parent object while deserializing a JSON using Gson . In your case you have list of aggregators where inner edges point to other aggregators on the same list. I propose to change a little bit your model and add new Node
property to Edge
class. Also, To avoid serialisation I used transient
keyword. You can change it and use @Expose
annotation but in this case transient
is much simpler. I added SerializedName
annotation to make properties in class with better names:
class Node {
@SerializedName("ID")
private int id;
private String name;
private double latitude, longitude;
private int previous = 0;
private boolean visited = false;
private double distance = Double.MAX_VALUE;
@SerializedName("Edge")
private List<Edge> edges;
// getters, setters, toString
}
class Edge {
@SerializedName("destination_id")
private int destinationId;
private transient Node destinationNode;
private double weight;
// getters, setters, toString
}
I changed a little bit JSON
to have reference:
[
{
"ID": 1001,
"name": "Egnatia-3isSeptembriou/Anatolika",
"latitude": 40.626216,
"longitude": 22.959864,
"Edge": [
{
"destination_id": 1030,
"weight": 6
},
{
"destination_id": 1002,
"weight": 12
}
]
},
{
"ID": 1002,
"name": "Egnatia-3isSeptembriou/Boreia",
"latitude": 40.626055,
"longitude": 22.959845,
"Edge": [
{
"destination_id": 1025,
"weight": 3
},
{
"destination_id": 1001,
"weight": 5
}
]
}
]
Now, we can deserialise classes from given payload
and set references after that.
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken;
import java.io.File;
import java.io.FileReader;
import java.lang.reflect.Type;
import java.util.List;
public class GsonApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
Gson gson = new GsonBuilder()
.setPrettyPrinting()
.create();
Type nodesType = new TypeToken<List<Node>>() {}.getType();
List<Node> nodes = gson.fromJson(new FileReader(jsonFile), nodesType);
nodes.forEach(node -> {
nodes.forEach(node1 -> {
node1.getEdges().forEach(edge -> {
if (node.getId() == edge.getDestinationId()) {
edge.setDestinationNode(node);
}
});
});
});
nodes.forEach(System.out::println);
}
}
Above code prints:
Node{id=1001, name='Egnatia-3isSeptembriou/Anatolika', latitude=40.626216, longitude=22.959864, previous=0, visited=false, distance=1.7976931348623157E308, edges=[Edge{destinationId=1030, destinationNodeIsSet=false, weight=6.0}, Edge{destinationId=1002, destinationNodeIsSet=true, weight=12.0}]}
Node{id=1002, name='Egnatia-3isSeptembriou/Boreia', latitude=40.626055, longitude=22.959845, previous=0, visited=false, distance=1.7976931348623157E308, edges=[Edge{destinationId=1025, destinationNodeIsSet=false, weight=3.0}, Edge{destinationId=1001, destinationNodeIsSet=true, weight=5.0}]}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.