3种方式解决iterator迭代器并发修改异常ConcurrentModificationException
在使用迭代器的时候,时长会遇到 ConcurrentModificationException(并发修改异常)
这也是很多人头疼的问题
并发修改异常产生的原因
在使用迭代器迭代集合的同时,使用原集合修改元素;如果迭代器发现自己和集合不一样,就会抛出 ConcurrentModificationException 异常。
先拿出我写的小案例:
Collection<String> list = new ArrayList<>(); list.add("JAVA"); list.add("Python"); list.add("PHP"); Iterator<String> it = list.iterator(); while(it.hasNext()) { if (it.next().equals("PHP")) { list.add("我全都要"); } }
一运行,就抛异常
Exception in thread "main" java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909) at java.util.ArrayList$Itr.next(ArrayList.java:859) at Test.main(Test.java:13)
看看源码:
at java.util.ArrayList$Itr.next(ArrayList.java:859)
public E next() { checkForComodification(); int i = cursor; if (i >= size) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i + 1; return (E) elementData[lastRet = i]; }
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); }
modCount 为 ArrayList 的类成员变量,用来记录其变化次数;而 expectedModCount 作为迭代器成员变量,则存储了 iterator 初始化时记录到的 ArrayList 中的 modCount 值。如果 modConut 和 expectedModCount 不相等,则抛出 ConcurrentModificationException 异常。
解决方法
这里我使用3种解决方案
- 使用列表迭代器
- 不使用迭代器遍历,使用普通for遍历
- 使用toArray
第一种:使用列表迭代器
List<String> list = new ArrayList<>(); list.add("JAVA"); list.add("Python"); list.add("PHP"); ListIterator<String> it = list.listIterator(); while(it.hasNext()){ if (it.next().equals("PHP")) { // list.add("以上几个"); //这里注意:直接修改原集合会抛出并发修改异常 it.add("我全都要"); } } System.out.println(list);
输出结果
[JAVA,Python,PHP,我全都要]
第二种:不使用迭代器遍历,使用普通for遍历
ArrayList<String> list = new ArrayList<>(); list.add("JAVA"); list.add("Python"); list.add("PHP"); for (int i = 0; i < list.size(); i++) { if (list.get(i).equals("PHP")) { list.remove("我全都要"); list.add("C++"); } } System.out.println(list);
输出结果
[JAVA,C++]
第三种:使用toArray
ArrayList<String> list = new ArrayList<>(); list.add("JAVA"); list.add("Python"); list.add("PHP"); Object[] obj = list.toArray(); for (int i = 0; i < obj.length; i++) { if (obj[i].equals("PHP")) { list.add(0,"今晚学习"); } } System.out.println(list);
输出结果
[今晚学习,JAVA,PHP]
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。