Ocasta Eshu
Ocasta Eshu

Reputation: 851

NoSuchElementException in for each loop with ArrayList<Integer>

The class below is meant to index the location of words by line. The method that is throwing an error is meant to append the index of a separate document on the current index. That is, if there are 6 lines in the first document, the first line of the appended document should be indexed as line 7.

public class DocumentIndex {
  // a NavigableMap implementation to store indexed words and their locations
  private TreeMap<String, ArrayList<Integer>> map = new TreeMap<String, ArrayList<Integer>>();

    /**
     * A method to append another index onto the main index
     * @param       indexAppendix       the additional index to be appended onto the main index
     */
  public void append(DocumentIndex indexAppendix){
    if(indexAppendix == null){
        throw new NullPointerException();
    }
    Integer docEnd = 0;                                 // the last line recorded in the main index
    Set<String> set = map.keySet();                     // a Set of the key values from map
    //select each key
    for(Iterator<String> iter = set.iterator(); iter.hasNext();){
        String key = iter.next();                       // the current key value
        // for each key select contents and determine the highest value
        for(Iterator<Integer> iter2 = this.find(key).iterator(); iter2.hasNext();){
            Integer compare = iter2.next();             // the key index current value
            if(compare>docEnd){
                docEnd=compare;
            }
        }
    }

    // for each key find an index value
    for(Iterator<String> iter = set.iterator(); iter.hasNext();){
        String key = iter.next();                       // the current key value
        // for each index value map that value adjusting for the length of the original document
        ArrayList<Integer> toAdd = new ArrayList<Integer>();
        for(Iterator<Integer> iter2 = this.find(key).iterator(); iter2.hasNext();){
            Integer addIter = iter2.next();
            toAdd.add(addIter); // the current index value
        }

        /**
         *Below is the loop in which the error is thrown
         */
        for(Iterator<Integer> iter3 = toAdd.iterator(); iter.hasNext();){

            Integer addIter = iter3.next();      // The error is thrown on this line

            map.get(key).add(addIter+docEnd);
        }
    }
}

What am I doing wrong?

Upvotes: 1

Views: 502

Answers (2)

Stephen C
Stephen C

Reputation: 718856

Louis Wasserman has nailed it.

I just want to point out that if you'd used the "new" Java for loop syntax, your code would be a lot simpler, and wouldn't (couldn't!!) have made that mistake in the first place. For example, here's roughly what your code would look like with the "new" for syntax:

    ...
    Integer docEnd = 0;
    Set<String> set = map.keySet();  
    for (String key : set) {
         for (Integer compare : this.find(key)) {
             if (compare < docEnd){
                  docEnd = compare;
             }
         }
    }

    for (String key : set) {
        ArrayList<Integer> toAdd = new ArrayList<Integer>();
        for (String add : this.find(key)) {
            toAdd.add(add); 
        }
        for (Integer add : toAdd) {
            map.get(key).add(add * docEnd);
        }
    } 

Isn't that so much more readable?


I put "new" in quotes because this syntax was introduced in Java 5 which was release in 2004. It should be part of the standard reportoire of all practicing Java programmers ... and instructors ... by now.

Please don't copy and paste the above code. It is only intended to illustrate my point.

Upvotes: 4

Louis Wasserman
Louis Wasserman

Reputation: 198103

The loop condition in the problematic loop should be iter3.hasNext(), not iter.hasNext().

Upvotes: 3

Related Questions