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

Java中Iterator.remove()抛出java.lang.IllegalStateException问题(火箭物品装载场景)

解决迭代器移除元素时的IllegalStateException问题

嘿,我看看你的问题——你遇到的IllegalStateException完全是因为迭代器的使用方式违反了它的核心规则,咱们先揪出问题根源,再修正代码。

问题根源

你的代码里有两个致命问题:

  1. 迭代器使用违规:Java的ArrayList迭代器要求,每次调用remove()必须紧跟在next()之后,而且一个next()只能对应一次remove()。但你在原代码的内层while循环里,只调用了一次iterator.next()拿到tempItem,却可能多次执行iterator.remove(),这直接触发了异常。
  2. 装载逻辑错误:你原代码的逻辑是拿一个物品反复尝试装到火箭里,这既不符合实际装载逻辑(应该尽可能给每艘火箭装更多不同物品),还会导致死循环(如果当前物品装不下的话)。

修正后的代码

下面是调整后的loadU2方法,完全解决了这两个问题:

public ArrayList<Rocket> loadU2(ArrayList<Item> loadItems) {
    ArrayList<Rocket> U2Ships = new ArrayList<>();
    
    // 只要还有未装载的物品,就继续创建新火箭
    while (!loadItems.isEmpty()) {
        Rocket tempShip = new U2();
        Iterator<Item> iterator = loadItems.iterator();
        
        // 给当前火箭尽可能装载更多物品
        while (iterator.hasNext()) {
            Item tempItem = iterator.next();
            // 如果当前物品能被火箭运载,就装载并移除该物品
            if (tempShip.canCarry(tempItem)) {
                tempShip.carry(tempItem);
                iterator.remove(); // 这里安全,因为刚执行了next()
            }
            // 如果火箭已经达到最大载重,停止装载这艘火箭
            if (tempShip.currentWeight >= tempShip.weightLimit) {
                break;
            }
        }
        
        U2Ships.add(tempShip);
    }
    
    return U2Ships;
}

关键修正点说明

  1. 外层循环改为判断物品列表是否为空:确保所有物品都被处理,而不是只遍历一次迭代器。
  2. 每艘火箭重新获取迭代器:每次创建新火箭时,都基于当前剩余的物品列表生成迭代器,保证装载的是最新的未处理物品。
  3. 严格遵守迭代器规则:每次remove()都紧跟在next()之后,避免触发异常。
  4. 增加火箭满载判断:火箭达到最大载重后立即停止装载,避免不必要的遍历。

用你给出的简化示例测试:物品列表[3,5,5,8,1,2,3,5]、火箭限重11吨,这个代码会正确生成4艘火箭,完全符合你的预期结果。

内容的提问来源于stack exchange,提问作者FSEL

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 17:42:38