首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >java.lang.IllegalStateException in iterator.remove()

java.lang.IllegalStateException in iterator.remove()
EN

Stack Overflow用户
提问于 2021-05-30 13:07:29
回答 4查看 448关注 0票数 1

火箭类包含:canCarry(项目项)>检查该项目是否可以携带/随身携带用总重量更新权重。

currentweightmaxWeight=18 U2类是火箭包含的子级: tons项目类包含:名称要运输&重量。

在loadU2方法中,我试图访问一个项目列表,并将其添加到一个火箭中,直到到达该火箭的maxWeight为止。例如,我有216吨的物品要携带,退回12艘船的清单。

它在行java.lang.IllegalStateException中抛出iterator.remove().错误我不知道如何去做,但是它看起来不允许我在迭代时删除项目。

代码语言:javascript
复制
public ArrayList<Rocket> loadU2(ArrayList<Item> loadItems){
    //list of ships
    ArrayList<Rocket> U2Ships = new ArrayList<Rocket>();
    for(Iterator<Item> iterator = loadItems.iterator(); iterator.hasNext();) {      
        //create a new ship
        Rocket tempShip = new U2();
        Item tempItem = iterator.next();
        //loop over items check if it can be filled then remove the item that was filled.
        while(tempShip.currentWeight<tempShip.weightLimit) {
            if(tempShip.canCarry(tempItem)){
                tempShip.carry(tempItem);
                iterator.remove();
            }           
        }
        U2Ships.add(tempShip);
    }
    return U2Ships;
}   


Exception in thread "main" java.lang.IllegalStateException
    at java.base/java.util.ArrayList$Itr.remove(ArrayList.java:980)
    at Simulation.loadU1(Simulation.java:35)
    at Main.main(Main.java:14)

代码所做工作的简化示例:假设每艘船的maxWeight = 11吨ArrayList loadItems = 3,5,5,8,1,2,3,5吨

代码语言:javascript
复制
 - Ship[1]=[3,5,1,2]
 - new list to iterate over >> [5,8,3,5]
 - Ship[2]=[5,3]
 - new list to iterate over >> [8,5]
 - Ship[3]=[8]
 - new list to iterate over >> [5]
 - Ship[4]=[5]
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2021-05-30 14:24:47

请通过创建新的ArrayList来重写代码,而不是在自己的迭代器中更改现有的列表:

代码语言:javascript
复制
public ArrayList<Rocket> loadU2(ArrayList<Item> loadItems){
    //list of ships
    ArrayList<Rocket> U2Ships = new ArrayList<Rocket>();
    ArrayList<Item> updatedLoadItems = new ArrayList<Item>();
    for(Iterator<Item> iterator = loadItems.iterator(); iterator.hasNext();) {      
        //create a new ship
        Rocket tempShip = new U2();
        Item tempItem = iterator.next();
        //loop over items check if it can be filled then only leave the load item that was not fully filled.
        boolean addLoadItem = true;
        while(tempShip.currentWeight<tempShip.weightLimit) {
            if(tempShip.canCarry(tempItem)){
                tempShip.carry(tempItem);
                addLoadItem = false;
            }         
        }
        if (addLoadItem) {
          updatedLoadItems.add(tempItem);
        };
        U2Ships.add(tempShip);
    }
    loadItems.removeAll();
    loadItems.addAll(updatedLoadItems);
    return U2Ships;
} 

这不是最好的解决方案,但是要提供更好的解决方案,您需要更改public ArrayList<Rocket> loadU2(ArrayList<Item> loadItems)的签名。

您可以通过重构代码来改进代码。

提示:现在您的loadU2方法尝试同时完成这两件事:更改loadItems并创建U2Ships。这直接违反了的单一责任原则。试想一下,那个士兵会一边开枪一边扔手榴弹!当时只有一件事。

票数 1
EN

Stack Overflow用户

发布于 2021-05-30 14:28:10

问题在于:

代码语言:javascript
复制
while(tempShip.currentWeight<tempShip.weightLimit) {
    if(tempShip.canCarry(tempItem)){
        tempShip.carry(tempItem);
        iterator.remove();
    }           
}

您正在循环中调用iterator.remove()。如果条件tempShip.canCarry(tempItem)保持两次,则调用iterator.remove()两次,这是不允许的(第二次,该项已经删除)。

我不知道canCarry方法是如何实现的,但是请注意,如果tempShip.currentWeight<tempShip.weightLimit是真的,但是tempShip.canCarry(tempItem)是假的,那么循环将永远运行。

票数 1
EN

Stack Overflow用户

发布于 2021-05-30 14:22:18

使用listIterator而不是Iterator。

代码语言:javascript
复制
ListIterator<Book> iter = books.listIterator();
while(iter.hasNext()){
    if(iter.next().getIsbn().equals(isbn)){
        iter.remove();
    }
}

就像这里用过的。

Remove elements from collection while iterating

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67761499

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档