user2714543
user2714543

Reputation: 749

Iterator throwing illegalstateexception after calling .next()

//This method compares two ArrayLists of strings and compares whether the words in one array list contain the letters in the other.

    public static void remove()
    {
        //Create iterators for both stringList and letterList
        Iterator<String> iterWords = stringList.iterator();
        Iterator<String> iterLetters = letterList.iterator();

        //First while loop will go over all strings in stringList via the iterWords iterator
        while(iterWords.hasNext())
        {
            //iterWords now has a .next() call

            String word = iterWords.next();
            //Second while loop that should run over each letter in letterList and compare it to each word in stringList
            while(iterLetters.hasNext())
            {
                //iterLetter now has a .next() call
                String letter = iterLetters.next();
                //if statement to remove the entry in stringList if it does not contain the current letter.  It is this part that throws the illegalstateexception
                if(word.contains(letter) == false)
                {
                    //This is the line that is causing the illegalstateexceptions
                    iterWords.remove();
                }           
            }
        }
    }

Hello everyone, I am looking for some insight concerning an exception I am getting while iterating over two arraylists. I have simplified the above arraylists and removed any methods that are not relevant to the problem. I am getting an illegalstateexception on the last iterWords.remove(). In the outside while loop I have done iterWords.next(), so iterWords.remove() should be seeing something to remove.
I am guessing that this is throwing the exception because of the fact that I am calling iterWords.remove() from the inner while loop. Do you think this might be the case? Thank you for any insight that you can bring.

Upvotes: 3

Views: 1651

Answers (1)

JB Nizet
JB Nizet

Reputation: 692071

First, you should read, and post, the exception.

Second: you're calling remove() several times, after calling next() just once: as many times as there are letters that are not contained in the word.

Third: since you're always using the same letter iterator, once you've done the first word, you don't iterate on the letters anymore.

So you must:

  • stop iterating on letters as soon as you've removed the word
  • recreate the letter iterator at each iteration of the outer loop. Or better, just use a foreach loop: you don't need an iterator for the inner loop. Your code would be much simpler, readable and safer if you used methods:

    for (Iterator<String> it: words; it.hasNext(); ) {
        String word : it.next();
        if (anyLetterNotInWord(letters, word) {
            it.remove();
        }
    }
    

If you're on Java 8, this can be reduced to

words.removeIf(word -> anyLetterNotInWord(letters, word));

where anyLetterNotInWord() can be defined as

return letters.stream().anyMatch(letter -> !word.contains(letter));

Upvotes: 4

Related Questions