First look at a piece of code:
@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);
}
}
}
The above code will definitely throw java.util.ConcurrentModificationException
an exception when it is running, and it will be list.remove(string);
replaced with the list.add("gg")
same exception.
Enter ArrayList
line 909 of the source code:
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
Use ArrayList
of remove
the method, modCount
will be a plus, but expectedModCount
at the beginning of the cycle, the two are equal, by checkForComodification
the determination method throws ConcurrentModificationException
an exception.
When the method ArrayList
in the inner class Itr
is remove
used to remove the element, the above two attributes will be re-assigned to be equal to ensure the normal operation of the collection.
Change the above demo to the following code to run normally:
@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();
If it is replaced Iterator<String> iterator = list.iterator();
, there is another remove
method, but no add
method. The method of the two list List
is defined for the interface, in ArrayList
the, iterator()
return directly Itr()
, and listIterator()
returns an inner class ListItr
type, the class inherits Itr
and implements ListIterator
the interface.