我知道如果要从集合中删除循环,我会得到以下异常: java.util.ConcurrentModificationException
. 但我使用的是迭代器,它仍然会生成这个异常。你知道为什么,怎么解决吗?
HashSet<TableRecord> tableRecords = new HashSet<>();
...
for (Iterator<TableRecord> iterator = tableRecords.iterator(); iterator.hasNext(); ) {
TableRecord record = iterator.next();
if (record.getDependency() == null) {
for (Iterator<TableRecord> dependencyIt = tableRecords.iterator(); dependencyIt.hasNext(); ) {
TableRecord dependency = dependencyIt.next(); //Here is the line which throws this exception
if (dependency.getDependency() != null && dependency.getDependency().getId().equals(record.getId())) {
tableRecords.remove(record);
}
}
}
}
4条答案
按热度按时间acruukt91#
hashset迭代器的约定是,除了通过spcific迭代器的remove方法之外,不能从hashset中删除。从
dependencyIt
,您删除了一个项目,而不是通过调用其remove
所以它抛出一个ConcurrentModificationException
.当记录具有相同的记录id时,似乎要从哈希集中删除记录。重写记录的id不是更容易吗
equals
以及hashcode
方法以确保具有相同id的记录相等并且具有相同的哈希代码(如果说得通的话(当然)cmssoen22#
你必须使用
iterator.remove()
而不是tableRecords.remove()
只有在使用迭代器中的remove方法时,才能删除对其进行迭代的列表上的项。编辑:
当您创建迭代器时,它将开始计算应用于集合的修改。如果迭代器检测到某些修改是在没有使用其方法(或在同一集合上使用另一个迭代器)的情况下进行的,它就不能再保证它不会在同一个元素上传递两次或跳过一次,因此它抛出这个异常
这意味着您需要更改代码,以便只通过iterator.remove(并且只使用一个iterator)删除项
或
列出要删除的项,然后在完成迭代后删除它们。
8ehkhllq3#
问题是,在同一时间范围内有两个迭代器,它们相互“争斗”。解决问题的最简单方法是,如果找到匹配项,就跳出内部循环:
java
Iterator
每当在没有使用Iterator
. 你在使用嵌套迭代器,所以remove()
对其中一个发出的操作将导致另一个抛出Exception
如果继续使用。因此,如果您需要remove()
,然后需要在“outer”迭代器上执行此操作(您正在执行此操作),然后停止使用第二个迭代器(添加了break
语句不存在)。lrpiutwd4#
每次尝试获取下一个元素时,迭代器都会失败快速属性检查底层集合结构中的任何修改。如果发现任何修改,它将抛出concurrentmodificationexception。除了concurrenthashmap和copyonwritearraylist这样的并发集合类之外,集合类中所有迭代器的实现都是设计上很快失败的。
图片来源:谷歌
用一个例子你会更好地理解below:-