java.lang.IllegalStateException 在 iterator.remove()
java.lang.IllegalStateException in iterator.remove()
Rocket class contains: canCarry(Item item)>检查这个物品是否可以携带/ carry 用总重量更新权重。
U2 class 是 Rocket 的子项包含:currentweight、maxWeight =18吨
项目 class 包含:要运送的名称和重量。
在方法 loadU2 中,我试图访问一个项目列表并将其添加到一个火箭中,直到该火箭的 maxWeight到达 。 例如我有 216 吨的物品要运载返回 12 艘船的清单。
它在行 iterator.remove() 中抛出 java.lang.IllegalStateException 错误。我不知道该怎么做,但看起来它不允许我在迭代时删除项目。
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]
使用 listIterator 而不是 Iterator。
ListIterator<Book> iter = books.listIterator();
while(iter.hasNext()){
if(iter.next().getIsbn().equals(isbn)){
iter.remove();
}
}
喜欢这里使用。
Remove elements from collection while iterating
请通过创建新的 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
为真,而tempShip.canCarry(tempItem)
为假,你的循环将运行永远。
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 个问题:无穷大和 iterator.remove()。
Rocket class contains: canCarry(Item item)>检查这个物品是否可以携带/ carry 用总重量更新权重。
U2 class 是 Rocket 的子项包含:currentweight、maxWeight =18吨 项目 class 包含:要运送的名称和重量。
在方法 loadU2 中,我试图访问一个项目列表并将其添加到一个火箭中,直到该火箭的 maxWeight到达 。 例如我有 216 吨的物品要运载返回 12 艘船的清单。
它在行 iterator.remove() 中抛出 java.lang.IllegalStateException 错误。我不知道该怎么做,但看起来它不允许我在迭代时删除项目。
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]
使用 listIterator 而不是 Iterator。
ListIterator<Book> iter = books.listIterator();
while(iter.hasNext()){
if(iter.next().getIsbn().equals(isbn)){
iter.remove();
}
}
喜欢这里使用。
Remove elements from collection while iterating
请通过创建新的 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
为真,而tempShip.canCarry(tempItem)
为假,你的循环将运行永远。
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 个问题:无穷大和 iterator.remove()。