使用List迭代器遍历集合时,添加新的元素没有被遍历的问题
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("张一");
list.add("张二");
list.add("张三");
list.add("张四");
//使用 list 迭代器遍历
ListIterator<String> listit = list.listIterator();
while (listit.hasNext()) {
String str = listit.next();
System.out.println(str);
if (str.equals("张一")) {
//添加操作后会修改下一次要访问的元素的索引,所以第一次遍历时会跳过新加的元素
//想要遍历新加的元素,需要重新遍历一次
listit.add("张一一");
}
}
}
//List迭代器的next()方法
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];
}
//List迭代器add()方法
public void add(E e) {
checkForComodification();
try {
int i = cursor; //下一个要访问的元素的索引
ArrayList.this.add(i, e); //添加元素
cursor = i + 1; //指针右移一位
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
通过分析源码可以发现,当使用next()方法获取到“张一”(0索引位置)这个元素后,指针会指向下一个元素“张二”(1索引位置)。当使用add()方法添加新元素“张一一”时,会在1索引位置添加,添加结束时会也会把指针右移一位,指向下一个元素“张二”(2索引位置),所以新添加的元素不会在下轮遍历时被访问,遍历完的结果好像新元素没有被添加到集合一样。