
课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
当集合结构被修改,会抛出Concurrent Modification Exception。fail-fast会在以下两种情况下抛出ConcurrentModificationException
(1)单线程环境集合被创建后,在遍历它的过程中修改了结构。
注意remove()方法会让expectModcount和modcount相等,所以是不会抛出这个异常。
(2)多线程环境当一个线程在遍历这个集合,而另一个线程对这个集合的结构进行了修改。
如下:
privatestaticvoidtest0() { List<String> list =newArrayList<>(); list.add("a1"); list.add("a2"); list.add("a3"); list.add("a4"); list.add("a5"); list.add("a6"); list.add("a7"); list.add("a8");for(String s : list) { list.remove(s); } System.out.println(list); }
运行会抛出异常
java.util.ConcurrentModificationException
如果又想在遍历的时候做删除操作呢?借肋iterator,如下:
privatestaticvoidtest1() { List<String> list =newArrayList<>(); list.add("a1"); list.add("a2"); list.add("a3"); list.add("a4"); list.add("a5"); list.add("a6"); list.add("a7"); list.add("a8"); Iterator<String> iter =list.iterator();while(iter.hasNext()) { String str=iter.next(); System.out.println(str);//iter.remove();if(Randoms.random(1, 9) % 2 == 0) { iter.remove(); } } System.out.println(list); }
这里我们并没有用list.remove元素而是iter.reomve,但实际list中的元素已经被删除也没有抛异常,为什么会这样?
调试的时候我们发现iter.reomve执行最终调用的是ArrayList
public E remove(int index)
所以自然影响了原来的集合。
Iterator被创建之后会建立一个指向原来对象的单链索引表,当list删除元素里不会影响索引,Iterator.remove()方法会在删除当前迭代对象的同时维护索引的一致性。
我们再看段代码:
privatestaticvoidtest2() { List list2= Arrays.asList(newString[]{"a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8",}); Iterator iter2=list2.iterator();while(iter2.hasNext()) { String str=iter2.next(); System.out.println(str);//iter.remove();if(Randoms.random(1, 9) % 2 == 0) { iter2.remove(); } } System.out.println(list2); }
结果:
会抛出异常java.lang.UnsupportedOperationException
为什么呢?感觉跟test1是一样的?
我们查看源码Arrays:
publicstatic<T> List<T>asList(T... a) {returnnewArrayList<>(a); }/***@serialinclude*/privatestaticclassArrayList<E>extendsAbstractList<E>implementsRandomAccess, java.io.Serializable{...}
发现两个ArrayList并不是同一个类却取了同一个名字:
java.util.Arrays.ArrayList!=java.util.ArrayList
你还是你同一个名字却是另一个他....
java.util.Arrays.ArrayList并没有实现remove方法,所以也就抛出了UnsupportedOperationException就不足为其了!
看似简单的问题多想一点就好了!