0

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.

1
  • 1
    why don't you parse this JSON to POJO? Commented Mar 3, 2019 at 19:06

1 Answer 1

1

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 +
                '}';
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

@johnD, It looks like JSON after edit does not match POJO model. Is JSON valid? Check it using online tools. If you will not be able to fix it, edit your question and add new JSON payload and classes.
@johnD, Nations class should look the same.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.