Reputation:
I have the following JSON
data with an array of nations
.
Neighbouring
in the data JSON
file indicates which nations have neighbours with other nations. The id of the nation refers to the neighbouring nations id.
ie. Russia has Ukraine neighbouring it, Poland has Ukraine, and Ukraine has Poland and Russia neighbouring it, etc..
-all data is already imported with Jackson
How can I list the neighbouring nations for each nation? ie. How can I list that Ukraine has Russia and Poland as neighbours?
{
"nations" : [{
"id" : 1,
"name" : "Russia",
"population" : 1000000000,
"cities" : [{
"id" : 222,
"name" : "Moscow",
"population": 4884333
},{
"id" : 223,
"name" : "Kazan",
"population": 799343
}]
},{
I think, I could return the array [3]
with this line:
JSONArray array = value.getJSONObject("neighbouring").getJSONArray("1");
But not sure where to go from here, I'm very new to this language.
Upvotes: 0
Views: 263
Reputation: 38690
If you already use Jackson
it is good to create POJO
and deserialise JSON
payload to given POJO
structure. Your classes could look like below:
class Nations {
private List<Nation> nations;
private Map<Integer, List<Integer>> neighbouring;
public List<Nation> getNations() {
return nations;
}
public void setNations(List<Nation> nations) {
this.nations = nations;
}
public Map<Integer, List<Integer>> getNeighbouring() {
return neighbouring;
}
public void setNeighbouring(Map<Integer, List<Integer>> neighbouring) {
this.neighbouring = neighbouring;
}
@Override
public String toString() {
return "Nations{" +
"nations=" + nations +
", neighbouring=" + neighbouring +
'}';
}
}
class Nation {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Nation{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
Now, when we have model, we can try to parse and print neighbours for each country:
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class JsonApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
ObjectMapper mapper = new ObjectMapper();
Nations nations = mapper.readValue(jsonFile, Nations.class);
// To make lookup fast create map id -> name
Map<Integer, String> id2Name = new HashMap<>();
nations.getNations().forEach(nation -> id2Name.put(nation.getId(), nation.getName()));
Map<Integer, List<Integer>> neighbouring = nations.getNeighbouring();
nations.getNations().forEach(nation -> {
List<String> neighbours = neighbouring.get(nation.getId())
.stream().map(id2Name::get).collect(Collectors.toList());
System.out.println(nation.getName() + " => " + neighbours);
});
}
}
Above code prints:
Russia => [Ukraine]
Poland => [Ukraine]
Ukraine => [Russia, Poland]
For more information, read:
EDIT
Your model after changing JSON
could look like below:
abstract class Area {
protected int id;
protected String name;
protected int population;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPopulation() {
return population;
}
public void setPopulation(int population) {
this.population = population;
}
}
class Nation extends Area {
private List<City> cities;
public List<City> getCities() {
return cities;
}
public void setCities(List<City> cities) {
this.cities = cities;
}
@Override
public String toString() {
return "Nation{" +
"id=" + id +
", name='" + name + '\'' +
", population=" + population +
", cities=" + cities +
'}';
}
}
class City extends Area {
@Override
public String toString() {
return "City{" +
"id=" + id +
", name='" + name + '\'' +
", population=" + population +
'}';
}
}
Upvotes: 1