Java 爪哇语;ConcurrentModificationException“;迭代时出现运行时错误。下一步()

Java 爪哇语;ConcurrentModificationException“;迭代时出现运行时错误。下一步(),java,exception,iterator,arraylist,runtime-error,Java,Exception,Iterator,Arraylist,Runtime Error,根据运行时错误消息,异常发生在以下行中 VirusData v = iteratorVirusDB.next(); VirusData是一个具有构造函数和重载构造函数的类,其中包含数据库中每个病毒的特定信息,例如 字符串vName 字符串定义 超载 具有标记化定义的数组(按X长度分组) 带有LCS令牌的数组 随坡度浮动 类型的iteratorVirusDB是VirusDB的.iterator(),如下所示: Iterator<VirusData> iteratorVir

根据运行时错误消息,异常发生在以下行中

VirusData v = iteratorVirusDB.next();

VirusData
是一个具有构造函数和重载构造函数的类,其中包含数据库中每个病毒的特定信息,例如

  • 字符串vName
  • 字符串定义
超载

  • 具有标记化定义的数组(按X长度分组)
  • 带有LCS令牌的数组
  • 随坡度浮动

类型的
iteratorVirusDB
VirusDB
的.iterator(),如下所示:

Iterator<VirusData> iteratorVirusDB = virusDB.iterator();

最后,此方法中出现错误,该方法使用了上述所有方法:

private void selectDabataseMouseClicked(java.awt.event.MouseEvent evt) {
    while(iteratorVirusDB.hasNext()) {
        VirusData v = iteratorVirusDB.next();               //ERROR LINE
        String vSig = v.signature;                              
        v.tokens = tokenize.raw(vSig, true, tLength);
        ...
     }
     ...
}

为了让程序成功运行,我真的需要一些帮助和建议来解决这个问题。下面是完整的堆栈跟踪:

run:
Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException
        at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
        at java.util.AbstractList$Itr.next(AbstractList.java:343)
        at project_clean.Main.selectDabataseMouseClicked(Main.java:275)
        at project_clean.Main.access$100(Main.java:11)
        at project_clean.Main$2.mouseClicked(Main.java:76)
        at java.awt.AWTEventMulticaster.mouseClicked(AWTEventMulticaster.java:253)
        at java.awt.Component.processMouseEvent(Component.java:6270)
        at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
        at java.awt.Component.processEvent(Component.java:6032)
        at java.awt.Container.processEvent(Container.java:2041)
        at java.awt.Component.dispatchEventImpl(Component.java:4630)
        at java.awt.Container.dispatchEventImpl(Container.java:2099)
        at java.awt.Component.dispatchEvent(Component.java:4460)
        at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4577)
        at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4247)
        at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
        at java.awt.Container.dispatchEventImpl(Container.java:2085)
        at java.awt.Window.dispatchEventImpl(Window.java:2478)
        at java.awt.Component.dispatchEvent(Component.java:4460)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

显而易见的解释是,您在调用之间修改了
virusDB
。在使用迭代器进行迭代时,不得修改向量(通过
迭代器
/
列表迭代器
方法除外)

这段代码将始终抛出一个
ConcurrentModificationException

import java.util.*;

class VirusData {
}

public class Test {

    public static void main(String[] args) {

        List<VirusData> list = new ArrayList<VirusData>() {{
            add(new VirusData());
            add(new VirusData());
            add(new VirusData());
        }};

        Iterator<VirusData> iterator = list.iterator();

        iterator.next();

        list.remove(0);
        VirusData s = iterator.next();
    }
}

当您在同时对其进行迭代的同时对其进行修改时,会发生并发修改异常。因此,如果您正在修改列表,并且在对其进行迭代时发生了这种情况,请检查您的代码。

当您从结构上修改
ArrayList
时,迭代器将无效。将迭代器保存为成员之间的类状态是可疑的。你为什么这么做?我刚刚回答了一个关于ConcurrentModificationException的问题。。。嗯,我真的不知道迭代器是如何工作的,我最近才发现迭代器是存在的,所以我只是通过尝试和错误来学习。因此,如果我理解正确,我不应该这样做
Iterator Iterator virusDB=virusDB.Iterator()?但是我怎么能重复这样的事情呢<代码>VirusData v=virusDB.iterator().next()?谢谢你的建议啊,请使用copy+paste作为StackTrace,而不是屏幕截图。@Paŭlo:改变了这一点,谢谢你的建议,但是如果一个程序在这种情况下不断修改一个列表,你怎么能遍历它呢?你可以使用一个索引,
i
,将
hasNext
替换为
i
next()
yourList.get(i)
。非常感谢,你在回答中提出的建议奏效了。但是现在我很困惑,当我做
v.tokens=tokenize.raw(vSig,true,tllength)
(在您的建议中省略)不会因为修改序列中的元素而违反规则。或者术语
修改
仅适用于集合“大小”,以便单词仅在添加/删除项目时违反?列表不关心内容对象本身是否在更改,它只关心结构修改时,例如添加和删除元素,以及可能用另一个元素替换一个元素(
set(…)
-也只有这些是对列表的修改。当然,如果您的程序是多线程的,通常不应该在另一个线程中使用对象时修改它们,因此请使用适当的同步。如果您有两个线程在同一个列表上工作,并且您正在见证
ConcurrentModificationException
,那么这意味着您r操作不是线程安全的,切换迭代样式以避免异常可能只会导致其他预期较低的异常。例如,一旦传递
i
检查最后一个元素,然后另一个线程可以在访问它之前删除任何元素,您将导致
IndexOutOfBoundsException
,这可能没有什么意义。要解决此问题,请在迭代时复制数组,或添加同步。
import java.util.*;

class VirusData {
}

public class Test {

    public static void main(String[] args) {

        List<VirusData> list = new ArrayList<VirusData>() {{
            add(new VirusData());
            add(new VirusData());
            add(new VirusData());
        }};

        Iterator<VirusData> iterator = list.iterator();

        iterator.next();

        list.remove(0);
        VirusData s = iterator.next();
    }
}
private void selectDabataseMouseClicked(java.awt.event.MouseEvent evt) {
    Iterator<VirusData> iteratorVirusDB = virusDB.iterator();
    while(iteratorVirusDB.hasNext()) {
        VirusData v = iteratorVirusDB.next();
        String vSig = v.signature;