迭代 .next() 时出现 Java "ConcurrentModificationException"运行时错误

标签 java exception iterator arraylist runtime-error

<分区>

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

VirusData v = iteratorVirusDB.next();

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

  • 字符串 vName
  • 字符串 vDefinition

重载

  • 具有标记化定义的数组(按 xLength 分组)
  • 包含 LCS 代币的数组
  • 成绩 float

iteratorVirusDB类型 <VirusData>VirusDB 的 .iterator() ,如下图:

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

VirusDB<VirusData> 类型的 ArrayList我在哪里存储病毒对象(此时的名称和定义)以便我以后可以使用它们。

ArrayList <VirusData> virusDB = new ArrayList<VirusData>();

最后,错误发生在使用上述所有解释的方法中:

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);
        ...
     }
     ...
}

我真的需要一些帮助和建议来解决这个问题,以便让程序成功运行。下面是完整的 StackTrace:

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。在使用迭代器进行迭代时,不得修改 vector (通过 Iterator/ListIterator 方法除外)。

这段代码将总是抛出一个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();
    }
}

来自ConcurrentModificationException的文档:

For example, it is not generally permissible for one thread to modify a Collection while another thread is iterating over it. In general, the results of the iteration are undefined under these circumstances. Some Iterator implementations (including those of all the general purpose collection implementations provided by the JRE) may choose to throw this exception if this behavior is detected. Iterators that do this are known as fail-fast iterators, as they fail quickly and cleanly, rather that risking arbitrary, non-deterministic behavior at an undetermined time in the future.

Note that this exception does not always indicate that an object has been concurrently modified by a different thread. If a single thread issues a sequence of method invocations that violates the contract of an object, the object may throw this exception. For example, if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will throw this exception.

如果您打算在每次调用该方法时遍历整个数据库,我建议您这样做

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

关于迭代 .next() 时出现 Java "ConcurrentModificationException"运行时错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5146113/

相关文章:

java - 带有自定义注释的 Guice 动态注入(inject)

java - 为什么我必须提供标识符?

C++ 迭代器、接口(interface)和指针

c++ - 无法分配给 mapType::const_iterator? ("no operator = matches")

带有抽象方法的Java继承

java - 在 GWT (Google Web Toolkit) 中向客户端抛出异常

c++ - 如何处理 libstdc++ 跨执行边界抛出异常

c++ - STL 迭代器 - 目的

java - RecyclerView 只在 List 中添加一项,而不是添加所有条目

java - 在 Java 中抛出异常