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;