[英]java.lang.IllegalStateException in iterator.remove()
Rocket class contains: canCarry (Item item)>checks if this item can be carried/ carry updates the weight with total weight. Rocket class 包含: canCarry (物品)>检查该物品是否可以携带/携带更新重量与总重量。
U2 class is child of Rocket contains: currentweight , maxWeight =18 tons Item class contains: name to be shipped & weight. U2 class 是 Rocket 的子代 包含:当前重量,最大重量 =18 吨 项目class包含:要运输的名称和重量。
In the method loadU2 I am trying to access a list of items and adding it into one rocket until maxWeight of that rocket is reached.在loadU2方法中,我试图访问项目列表并将其添加到一个火箭中,直到达到该火箭的maxWeight 。 For example I have 216 tons of items to carry returning a list of 12 ships.
例如,我有 216 吨的物品要携带返回 12 艘船的清单。
It throws me java.lang.IllegalStateException error in the line iterator.remove() .它在iterator.remove()行中向我抛出java.lang.IllegalStateException错误。 I do not know how to go about it, but it looks like it is not allowing me to remove the items while iterating.
我不知道如何 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)
Simplified example of what the code is doing: Assuming maxWeight for each ship = 11 tons ArrayList loadItems = [3,5,5,8,1,2,3,5] tons代码执行的简化示例:假设每艘船的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]
Please, rewrite your code by creating new ArrayList, instead of changing the existing list inside its own iterator:请通过创建新的 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;
}
This is not the best solution, but to provide a better solution, you need to change the signature of public ArrayList<Rocket> loadU2(ArrayList<Item> loadItems)
这不是最好的解决方案,但要提供更好的解决方案,您需要更改
public ArrayList<Rocket> loadU2(ArrayList<Item> loadItems)
的签名
You can try to improve your code by refactoring it.您可以尝试通过重构来改进您的代码。
Hint: right now your loadU2 method tries to do both things at the same time: change loadItems and create U2Ships .提示:现在你的loadU2方法试图同时做这两件事:改变loadItems并创建U2Ships 。 This is a direct violation of the single responsibility principle .
这直接违反了单一责任原则。 Try to imagine the soldier who would try to shoot the gun and throw grenade at the same time.
试着想象一个士兵会同时开枪和投掷手榴弹。 One thing at the time.
当时有一件事。
The problem is here:问题在这里:
while(tempShip.currentWeight<tempShip.weightLimit) {
if(tempShip.canCarry(tempItem)){
tempShip.carry(tempItem);
iterator.remove();
}
}
You are calling iterator.remove()
within a loop.您正在循环中调用
iterator.remove()
。 If the condition tempShip.canCarry(tempItem)
holds twice, you call iterator.remove()
twice, and this is not allowed (the second time, the item is already removed).如果条件
tempShip.canCarry(tempItem)
成立两次,则调用iterator.remove()
两次,这是不允许的(第二次,该项目已被删除)。
I don't know how the method canCarry
is implemented, but note that if it is the case that tempShip.currentWeight<tempShip.weightLimit
is true, but tempShip.canCarry(tempItem)
is false, your loop will run forever.我不知道
canCarry
方法是如何实现的,但请注意,如果tempShip.currentWeight<tempShip.weightLimit
为 true,但tempShip.canCarry(tempItem)
为 false,则您的循环将永远运行。
use listIterator instead of Iterator.使用 listIterator 而不是 Iterator。
ListIterator<Book> iter = books.listIterator();
while(iter.hasNext()){
if(iter.next().getIsbn().equals(isbn)){
iter.remove();
}
}
like used here.喜欢这里使用。
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;
}
Thank you guys for the help, this should fix 2 problems: infinity, and the iterator.remove().谢谢你们的帮助,这应该解决 2 个问题:infinity 和 iterator.remove()。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.