注意:我知道该Iterator#remove()方法。
Iterator#remove()
在下面的代码示例中,我不明白为什么List.remove在main方法抛出ConcurrentModificationException,但不是在remove方法。
List.remove
main
ConcurrentModificationException
remove
public class RemoveListElementDemo { private static final List<Integer> integerList; static { integerList = new ArrayList<Integer>(); integerList.add(1); integerList.add(2); integerList.add(3); } public static void remove(Integer toRemove) { for(Integer integer : integerList) { if(integer.equals(toRemove)) { integerList.remove(integer); } } } public static void main(String... args) { remove(Integer.valueOf(2)); Integer toRemove = Integer.valueOf(3); for(Integer integer : integerList) { if(integer.equals(toRemove)) { integerList.remove(integer); } } } }
原因如下:正如Javadoc中所说:
Javadoc
此类的迭代器和listIterator方法返回的迭代器是快速失败的:如果在创建迭代器后的任何时间以任何方式对列表进行结构修改,除非通过迭代器自己的remove或add方法,否则迭代器将抛出ConcurrentModificationException。
listIterator
该检查是在next()迭代器的方法中完成的(如你在stacktrace中所看到的)。但是,next()只有在hasNext()传递的结果为true时,我们才能实现该方法,这是每个方法调用此方法以检查是否满足边界的要求。在你的remove方法中,当hasNext()检查是否需要返回另一个元素时,将看到它返回了两个元素,现在在删除一个元素之后,列表仅包含两个元素。因此,一切都变桃了,我们已经完成了迭代。不会进行并发修改检查,因为这是在next()从未调用过的方法中完成的。
next()
hasNext()
true
接下来,我们进入第二个循环。在删除第二个数字之后,hasNext方法将再次检查是否可以返回更多值。它已经返回了两个值,但是列表现在只包含一个。但是这里的代码是:
public boolean hasNext() { return cursor != size(); }
1!= 2,因此我们继续执行该next()方法,该方法现在意识到有人一直在弄乱列表并触发异常。
1!= 2
希望能解决你的问题。
摘要 List.remove()ConcurrentModificationException从列表中删除倒数第二个元素时不会抛出该异常。
List.remove()ConcurrentModificationException