Skip to content
Advertisement

map inside a map – Need data in specific format

I have a requirement where I want to read multiple project pom files and display data in below format

  {
 "java" : {"1.7" : ["project1"],"1.8": ["project2"]},
 "junit" : {"4.12" : ["project1"]},
 "hsqldb" : {"1.8" : ["project3"],"1.1": ["project6"]}
   }

My coding is getting input on project , ver and technlogy and displaying, but however I couldnt second value inside the internal

private void addTechnologyData(String projName,String techName,String ver)
{
    String keyFormat=techName;
    if (technologyMap.containsKey(keyFormat)) {
        Map preValue=technologyMap.get(keyFormat);
        if(!preValue.containsValue(projName)) {
            Map<String,String> temp = new HashMap();
            temp=preValue;
            temp.put(ver,projName);
            technologyMap.put(keyFormat, temp);
        }
    } else {
       Map<String,String> projectVersiomap = new HashMap();
       projectVersiomap.put(ver,projName);
       technologyMap.put(keyFormat, projectVersiomap);
    }
}

Please help me understand why I couldnt add 2nd key value pair to Internal map? Is there a better way than what Im doing?

Answer

If my understanding is correct, you are expecting more than one project per version (since you have an array), so your Map is preventing this, you can only have one value per key. You can use a List like Map<String,Map<String, List<String>>> but I would suggest to use some POJO to keep the code cleaner.

Create a Technology class that will hold a list of Project for each version in a Map. This would look like :

public class Technology{

    private String name;
    private Map<String, List<Project>> projects;

    public Technology(String name){
        this.name = name;
        this.projects = new HashMap<>();
    }

    public void addProjectToVersion(String version, Project project){
        List<Project> l = this.projects.get(version);
        if(l == null){ //doesn't exist
            l = new ArrayList<>();
            this.projects.put(version, l);
        }
        l.add(project);
    }
}

Here, the logic is in the POJO. You just need to use a Collection to hold your instance, a Map if you like, or a List (implement equals and hashCode to recover easily the instance). And you can use it like :

private Map<String, Technology> techs = new HashMap<>();
....
public void addProject(String tech, String version, String projectName){
    Technology t = techs.get(tech);
    if(t == null){ //doesn't exist
         t = new Technology(tech);
         techs.put(tech, t);
    }
    t.addProjectToVersion(version, new Project(projectName));
}

public void insertData(){
    addProject("java", "1.7", "project1");
    addProject("java", "1.7", "project2");
    addProject("java", "1.8", "project1");
    addProject("junit", "4.12", "project1");

    System.out.println(techs);
}

This will input correctly :

{junit={4.12=[project1]}, java={1.7=[project1, project2], 1.8=[project1]}}

Note that I reused your logic, based on the requirements it could be better to have a List<Project> holding each Technology with the version. But this is based on the context.

Advertisement