1

I am trying to create a HashMap in a HashMap so it will be easier for me to access elements of it in the future as shown below.

The problem is it only repeating the last elements of the while loop and not the rest of it.

HashMap<String,String> result = new HashMap<>();
HashMap<Integer, HashMap<String,String>> fr = new HashMap<>();

int i = 0;
try {
    ResultSet rq = qexec.execSelect();
    // ResultSetFormatter.out(System.out, rq, query);

    // get result from SPARQL query
    while (rq.hasNext()) {
        QuerySolution soln = rq.next();
        id = soln.getLiteral("?id").getLexicalForm();
        //...
        result.put("id",id);
        //...
        if (soln.getLiteral("?wateruse") != null) {
            wateruse = soln.getLiteral("?wateruse").getLexicalForm();
            //...
            result.put("wateruse",wateruse);
        } else {
            System.out.println("NO");
        }               

        fr.put(i, result);
        i++;
    }
} finally {
    qexec.close();
}

This is how the result should be:

John001
High usage
John002
John003
Smith001
Moderate
Smith002
Smith003
...
Kevin001
Low usage

But fr only repeats Kevin001 and Low usage without the rest.

I've tried to put fr.put(i,result) outside the loop but that still does not give the correct result.

EDIT

I tried to print all elements from fr that shows the repeating elements.

finally {

            qexec.close();
        }


        for (int index : fr.keySet()) {
              for(Map.Entry<String, String> entry :result.entrySet()) {
                System.out.println(index + " = " + entry.getKey() + " : " + entry.getValue());
            }
        }

UPDATE - SOLUTION

Declare HashMap inside the loop as mentioned in comments below.

To print nested HashMap, no need to use result. I did as shown below and it prints both outermap and innermap as well.

        for (int k=0;  k < fr.size(); k++) {
            HashMap<String,String> innermap = fr.get(k);
            for(Map.Entry<String, String> e : innermap.entrySet()) {
                System.out.println(k + " = " + e.getKey() + " : " + e.getValue());
            }
        }
kaixas K
  • 111
  • 12
  • creating map object inside loop will solve you problem. like : result = new HashMap<>(); – Devram Kandhare Aug 23 '17 at 03:38
  • In your edit to print all elements, you should not be using "result.entryset" (which has nothing to do with the outer for loop), but "fr.get(index)" – racraman Aug 23 '17 at 04:01
  • You're printing the values from the last entry in the map because you're printing the `result` map. That will always have the data from the last iteration through the loop. Instead, get the values from `fr` as you loop through it (updated with details on how to do that). – nbrooks Aug 23 '17 at 04:01

2 Answers2

5

You're adding the same result map to your parent map each time through the loop. Create a new instance of result each time through the loop:

Map<String, String> result = new HashMap<>();
Map<Integer, Map<String, String>> fr = new HashMap<>();

int i = 0;
try {

    ResultSet rq = qexec.execSelect();

    while (rq.hasNext()) {

        // Create your new HashMap inside the loop:
        result = new HashMap<>();

        QuerySolution soln = rq.next();

        id = soln.getLiteral("?id").getLexicalForm();
        //...

        result.put("id",id);
        //...

        if (soln.getLiteral("?wateruse") != null) {

            wateruse = soln.getLiteral("?wateruse").getLexicalForm();
            //...
            result.put("wateruse",wateruse);
        }
        else {
            System.out.println("NO");
        }               

        fr.put(i,result);
        i++;
    }
}

To print the results from fr an its nested map, you can do something like this:

for (Map<String, String> map : fr.values()) {
    for(Map.Entry<String, String> e : map.entrySet()) {
        System.out.println(index + " = " + e.getKey() 
            + " : " + e.getValue());
    }
}
nbrooks
  • 18,126
  • 5
  • 54
  • 66
2

Try this a small change here, place the "result" map creation in while loop

Map<Integer, Map<String, String>> fr = new HashMap<>();

int i = 0;
try {

    ResultSet rq = qexec.execSelect();

    while (rq.hasNext()) {
        Map<String, String> result = new HashMap<>();

        QuerySolution soln = rq.next();

        id = soln.getLiteral("?id").getLexicalForm();
        //...

        result.put("id",id);
        //...

        if (soln.getLiteral("?wateruse") != null) {

            wateruse = soln.getLiteral("?wateruse").getLexicalForm();
            //...
            result.put("wateruse",wateruse);
        }
        else {
            System.out.println("NO");
        }               

        fr.put(i,result);
        i++;
    }
}

This for loop to print elemenets:

for (int i=0;i< fr.size();i++){
    Map<String,String> element= fr.get(i);
//  use the element here.

}
Umar Hussain
  • 3,461
  • 1
  • 16
  • 38