user11144777
user11144777

Reputation:

parsing JSON data in Java - stuck with id's

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

Answers (1)

Michał Ziober
Michał Ziober

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

Related Questions