【问题标题】:Iterator throwing illegalstateexception after calling .next()调用 .next() 后迭代器抛出非法状态异常
【发布时间】:2015-12-30 21:40:27
【问题描述】:
//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();
                }           
            }
        }
    }

大家好,我正在寻找一些关于迭代两个数组列表时遇到的异常的见解。我已经简化了上述数组列表并删除了与问题无关的任何方法。 我在最后一个 iterWords.remove() 上收到了非法状态异常。在外部 while 循环中,我已经完成了 iterWords.next(),因此 iterWords.remove() 应该看到要删除的内容。
我猜这是抛出异常,因为我从内部 while 循环调用 iterWords.remove() 。你认为可能是这种情况吗? 感谢您提供任何见解。

【问题讨论】:

  • 嗯...一个“比较”事物的方法不应该被称为remove
  • 是的,你说的很对。我将其命名为仅用于发布,以便读者知道这是发生 .remove() 问题的方法。

标签: java while-loop iterator illegalstateexception


【解决方案1】:

首先,您应该阅读并发布异常。

第二次:在只调用一次next() 之后,你又调用了几次remove():与单词中未包含的字母一样多。

第三:因为你总是使用相同的字母迭代器,一旦你完成了第一个单词,你就不再迭代字母了。

所以你必须:

  • 删除单词后立即停止迭代字母
  • 在外循环的每次迭代中重新创建字母迭代器。或者更好的是,只需使用 foreach 循环:内部循环不需要迭代器。 如果你使用方法,你的代码会更简单、更易读、更安全:

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

如果您使用的是 Java 8,这可以简化为

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

其中anyLetterNotInWord()可以定义为

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

【讨论】:

  • 非常感谢!是的,这绝对是问题所在。它现在就像一个魅力。关于 Java 8 的非常有趣的信息。与我令人困惑的方法相比,这似乎更容易使用 :)。再次感谢您!
  • 不客气。如果您不知道,表示感谢的方式是通过投票和/或接受答案。这也向其他人表明您的问题已得到解决。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多