List如何才能一边遍历,一边删除
程序员文章站
2022-04-11 19:29:38
...
这可能是很多新手第一时间想到的方法
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("baidu");
list.add("google");
for (String company : list) {
if (company.equals("baidu")) {
list.remove(company);
}
}
System.out.println(list);
}
但是如果试着执行会发现,程序会抛java.util.ConcurrentModificationException
异常(并发修改异常)。
为什么会抛java.util.ConcurrentModificationException
异常?
foreach循环在实际执行时,其实使用的是Iterator
,使用的核心方法是hasnext()
和next()
。调用next()
方法获取下一个元素时,第一行代码就是调用了checkForComodification();
,而该方法的核心逻辑就是比较modCount
和expectedModCount
这2个变量的值。
刚开始modCount
和expectedModCount
的值相等,第1次获取元素是没问题的。但是当执行完remove操作的时候modCount的值就被修改了
。再次checkForComodification的时候,就会
抛java.util.ConcurrentModificationException
异常。
正确删除的方法
使用Iterator的remove()方法
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("baidu");
list.add("google");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String company = iterator.next();
if (company.equals("baidu")) {
iterator.remove();
}
}
System.out.println(list);
}
为何iterator.remove()就不会报错?
iterator.remove()的时候,每次删除一个元素,都会将modCount
的值重新赋值给expectedModCount
,2个变量就相等了,这样就不会触发java.util.ConcurrentModificationException
异常。