[英]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.