I've got a method that returns a list of hashmaps (the data comes from a ResultSet). While trying to use an iterator to loop through the data and convert it to a String array, I was finding that the code was not working - It seemed to be losing half of my array data while doing the loop.
When swapping it to use a for loop rather than an iterator, the data was not lost. I tried using both an Iterator()
and ListIterator()
to no avail
Here is my original code (that wasn't working):
public String[][] getLayoutEdges() throws SQLException {
ArrayList<String[]> returnArray = new ArrayList<>();
List<HashMap> layoutEdges = db.getLayoutEdgesFromDatabase();
ListIterator<HashMap> edgesIterator = layoutEdges.listIterator();
while(edgesIterator.hasNext()) {
ArrayList<String> tmpList = new ArrayList<>();
tmpList.add(edgesIterator.next().get("fromnode").toString());
tmpList.add(edgesIterator.next().get("tonode").toString());
tmpList.add(edgesIterator.next().get("distance").toString());
String[] tmpStr = new String[tmpList.size()];
returnArray.add(tmpList.toArray(tmpStr));
}
String[][] rtn = new String[returnArray.size()][returnArray.size()];
return returnArray.toArray(rtn);
}
Here is the code that does work:
public String[][] getLayoutEdges() throws SQLException {
ArrayList<String[]> returnArray = new ArrayList<>();
List<HashMap> layoutEdges = db.getLayoutEdgesFromDatabase();
for(HashMap tmp : layoutEdges) {
ArrayList<String> tmpList = new ArrayList<>();
tmpList.add(tmp.get("fromnode").toString());
tmpList.add(tmp.get("tonode").toString());
tmpList.add(tmp.get("distance").toString());
String[] tmpStr = new String[tmpList.size()];
returnArray.add(tmpList.toArray(tmpStr));
}
String[][] rtn = new String[returnArray.size()][returnArray.size()];
return returnArray.toArray(rtn);
}
Can anybody tell me why the iterator wasn't working? I'm okay with using a for loop, i just can't for the life of me work out why the original iterator code I wrote wasn't keeping all my data. Wondering if there's a step i'm missing or whether I was trying to use the wrong solution.
You're calling edgesIterator.next()
three times for each iteration of the loop in your first snippet, which I'm pretty sure you don't want to do. Just don't do that:
while (edgesIterator.hasNext()) {
HashMap tmp = edgesIterator.next();
tmpList.add(tmp.get("fromnode").toString());
tmpList.add(tmp.get("tonode").toString());
tmpList.add(tmp.get("distance").toString());
String[] tmpStr = new String[tmpList.size()];
returnArray.add(tmpList.toArray(tmpStr));
}
As an aside, if you could avoid using raw types in your API, it would generally be cleaner - I'm talking about the use of HashMap
here.
I would also generally favour the second version of your code anyway - unless you need to use the iterator explicitly for some reason, let the syntactic sugar of the enhanced for loop do it for you automatically.
See more on this question at Stackoverflow