You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ListIterator.remove抛IllegalStateException及set调用后无异常原因解析

为什么ListIterator调用add后remove抛异常,set后remove却正常?

这事儿得从ListIterator的规则限制说起,尤其是remove()方法的调用前提——它可不是随时能调用的!

先搞懂remove()的核心要求

在ArrayList的ListIterator实现里,remove()有个硬性规则:只能在刚刚执行过next()或者previous()之后调用,而且中间不能穿插add()或者另一个remove()操作。

这背后是迭代器内部维护的一个lastRet变量,它记录了上一次通过next()/previous()访问的元素索引,remove()就是靠这个索引来定位要删除的元素。如果lastRet是-1(表示没有最近访问的元素),调用remove()就会直接抛出IllegalStateException。


第一段代码(add后remove)的问题分析

我们拆解这段代码的执行流程:

public class App { 
    public static void main( String[] args ) throws InterruptedException { 
        List<Integer> list = new ArrayList<>(); 
        list.add(3); list.add(2); list.add(1); 
        ListIterator<Integer> listIterator = list.listIterator(); 
        while(listIterator.hasNext()){
            listIterator.next(); // 1. 调用next(),lastRet被设为当前元素索引(比如第一次循环是0)
            listIterator.add(5); // 2. 调用add(),插入元素后,lastRet被重置为-1!
            listIterator.remove(); // 3. 此时lastRet是-1,迭代器找不到要删的元素,抛出异常
        } 
    } 
}

关键就在add()操作:它会把新元素插入到当前迭代器位置的前方,同时主动把lastRet重置为-1——因为add()并没有“选中”任何一个现有元素,迭代器的状态变成了“没有最近访问的元素”,这时候调用remove()自然不符合规则。


第二段代码(set后remove)正常的原因

再看这段代码的流程:

public class App { 
    public static void main( String[] args ) throws InterruptedException { 
        List<Integer> list = new ArrayList<>(); 
        list.add(3); list.add(2); list.add(1); 
        ListIterator<Integer> listIterator = list.listIterator(); 
        while(listIterator.hasNext()){
            listIterator.next(); // 1. 调用next(),lastRet被设为当前元素索引
            listIterator.set(5); // 2. 调用set(),只是修改lastRet指向的元素值,lastRet保持不变
            listIterator.remove(); // 3. 迭代器通过lastRet找到要删的元素(刚修改的那个),正常执行
        } 
    } 
}

set()操作的本质是修改已选中的元素,它不会改变lastRet的状态——lastRet依然保留着上一次next()访问的元素索引。所以这时候调用remove(),迭代器能准确找到要删除的元素,自然不会抛出异常。


总结一下

  • add()会改变迭代器的状态,清除上一次访问的元素标记(lastRet=-1),导致后续remove()找不到操作对象;
  • set()只是修改已选中的元素,不会改变迭代器的访问状态,所以remove()依然能基于之前的lastRet执行操作。

内容的提问来源于stack exchange,提问作者Karunakar Reddy L

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:40:33