javahashmapiteratornosuchelementexception

NoSuchElementException when HashMap Iterator hits empty line


Hi i'm doing some training on ArrayLists and HashMap.

I'm parsing a file with BufferedReader, add each line to the ArrayList readList and now I like to create a HashMap<String,Integer> map where the Key is the readList entry and the Value is the line count.

When i use a Lambda command so print the k,v everything works fine. However when i try to use the Iterator to save the k,v to variables, i'm getting a NoSuchElementException error. What am I doing wrong ? (Just fyi when i delete the empty line in the file, everything works fine)

        String sourceFile = "newtestfile.txt";
        BufferedReader br = new BufferedReader(new FileReader(sourceFile));
        String line = br.readLine();
        ArrayList<String> readListe = new ArrayList<>();  

        while(line != null){
            readListe.add(line);
            line = br.readLine();
        }

        HashMap<String,Integer> map = new HashMap<>();
        for(int i = 0; i<readListe.size() ;i++){
            map.put(readListe.get(i), i+1);
        }

        //map.forEach((k,v) -> System.out.println(k));
        Iterator<Map.Entry<String,Integer>> iterator2 = map.entrySet().iterator();
        while(iterator2.hasNext()){
            String key = iterator2.next().getKey();
            int value = iterator2.next().getValue();

            System.out.println(key + " " + value);
        }



**Source file:** 

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren
NewLine ipsum dolor sit amet, consetetur sadipscing elitr, 
This is line 3
//EMPTY LINE
John Doe
//END OF FILE

Solution

  • In your while(iterator2.hasNext()) loop you call iterator2.next() twice which means that the iterator advances twice each time.

    With the empty line present your input has an odd number of lines at that means the last time through the while loop there is no element left for the iterator2.next().getValue() call.

    It would be better to use the "for-each" idiom:

        for (Map.Entry<String, Integer> e: map.entrySet()) {
            String key = e.getKey();
            int value = e.getValue();
    
            System.out.println(key + " " + value);
        }