java面试题网站:www.javaoffers.com
源码分析List删除元素注意点,小心报错。并用一个小案例讲解记录笔记
/**
* 研究List 在删除的过程中注意点。
*/
@Test
public void test8(){
LinkedList<String> list = new LinkedList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
//生成一个迭代器,并复制 “修改次数” , 源代码:int expectedModCount = modCount;
//expectedModCount :为迭代器中的修改次数
//modCount : 为list集合中的修改次数
// 迭代下一个,调用的是下一个next(),此方法会调用检查checkForComodification() 方法
// 检查expectedModCount 和 modCount 是否相同,不同则会报错
//注意:删除最后一个元素则不会报错,因为hashNext() 敬返回false,则不会调用next(),也就不会checkForComodification()
// 所以就不会报错
for(String ele : list){
if("b".equals(ele)){
//remove方法中调用unlink(x)
//list.remove(ele); //更改了的modCount次数并没有 修改expectedModCount次数,源码:modCount++(在 unlink(x)方法中),
}
}
//可以通过迭代器,在迭代的过程删除,继续迭代 调用next(),不会报错,因为:
// iterator.remove() 会同时更改 modCoun 和 expectedModCount,所以两个mod变量是同步的
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()){
String next = iterator.next();
if("b".equals(next)){
//在 iterator.remove()中调用 unlink(x)(源码中modCount++),然后expectedModCount++,这会使两个mod变量是同步的。所以在下次next()中检查不会报错
iterator.remove();
}
}
}