先看一段代码:
@Test
public void test02(){
List<String> list = new ArrayList<>(8);
list.add("tom");
list.add("jack");
list.add("marry");
list.add("wuwl");
for(String string:list){
if("wuwl".equals(string)){
list.remove(string);
}
}
}
上面代码在运行过程中,肯定会抛出java.util.ConcurrentModificationException
异常的,将list.remove(string);
替换成list.add("gg")
,也是会抛出同样的异常的。
进入ArrayList
源码的909行:
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
使用ArrayList
的remove
方法后,modCount
会加一,但expectedModCount
在循环开始时,二者是相等的,在通过checkForComodification
方法判断后,就会抛出ConcurrentModificationException
异常。
而通过ArrayList
的内部类Itr
里面的remove
方法去移除元素时,会将上面的两个属性重新赋值为相等,保证集合的正常操作。
将上面的demo改成下面的代码即可正常运行:
@Test
public void test03(){
List<String> list = new ArrayList<>(8);
list.add("tom");
list.add("jack");
list.add("marry");
list.add("wuwl");
ListIterator<String> iterator = list.listIterator();
while(iterator.hasNext()){
if("wuwl".equals(iterator.next())){
iterator.remove();
iterator.add("gg");
}
}
System.out.println(list);
}
ListIterator<String> iterator = list.listIterator();
如果换成Iterator<String> iterator = list.iterator();
的话,则又有remove
方法,没有add
方法。list的两个方法在List
接口中都有定义,在ArrayList
中,iterator()
直接返回了Itr()
,而listIterator()
会返回一个内部类ListItr
类型,该类继承了Itr
并实现了ListIterator
接口。