繁体   English   中英

iterator.remove() 中的 java.lang.IllegalStateException

[英]java.lang.IllegalStateException in iterator.remove()

Rocket class 包含: canCarry (物品)>检查该物品是否可以携带/携带更新重量与总重量。

U2 class 是 Rocket 的子代 包含:当前重量,最大重量 =18 吨 项目class包含:要运输的名称和重量。

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

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

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] 吨

 - 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]

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

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 这直接违反了单一责任原则 试着想象一个士兵会同时开枪和投掷手榴弹。 当时有一件事。

问题在这里:

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为 true,但tempShip.canCarry(tempItem)为 false,则您的循环将永远运行。

使用 listIterator 而不是 Iterator。

ListIterator<Book> iter = books.listIterator();
while(iter.hasNext()){
    if(iter.next().getIsbn().equals(isbn)){
        iter.remove();
    }
}

喜欢这里使用。

迭代时从集合中删除元素

public ArrayList<Rocket> loadU2(ArrayList<Item> loadItems){
    //list of ships
    int shipNum=0;
    int itemsloaded=0;
    ArrayList<Rocket> U2Ships = new ArrayList<Rocket>();
    while(!loadItems.isEmpty()) {      
        System.out.println("number of ships created: "+shipNum++);
        //create a new ship
        Rocket tempShip = new U2();
        
        //loop over items check if it can be filled then only leave the load item that was not fully filled.
     
        while(iterator.hasNext()) {  
            Item tempItem = iterator.next();
            if(tempShip.canCarry(tempItem)){
                System.out.println("number of items loaded: "+(itemsloaded++));
                tempShip.carry(tempItem);
                iterator.remove();                                      
             
           } 
        }
        
        U2Ships.add(tempShip);
    }

    return U2Ships;
} 

谢谢你们的帮助,这应该解决 2 个问题:infinity 和 iterator.remove()。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM