Java 在两个位置循环通过LinkedLinkst会产生错误
所以我在用Java做一个小游戏,在这个游戏中,你有存储在LinkedList中的实体。在tick方法中,我遍历实体的LinkedList,如下所示:Java 在两个位置循环通过LinkedLinkst会产生错误,java,linked-list,iteration,Java,Linked List,Iteration,所以我在用Java做一个小游戏,在这个游戏中,你有存储在LinkedList中的实体。在tick方法中,我遍历实体的LinkedList,如下所示: @Override public void tick(float delta) { for (Entity e : entities) { e.tick(delta); } player.tick(delta); } 渲染方法也是如此 @Override public void render(Graphic
@Override
public void tick(float delta) {
for (Entity e : entities) {
e.tick(delta);
}
player.tick(delta);
}
渲染方法也是如此
@Override
public void render(Graphics g) {
g.setColor(Color.DARK_GRAY);
g.fillRect(0, 0, Game.WIDTH, Game.HEIGHT);
for(Entity e : entities) {
e.render(g);
}
player.render(g);
}
其中一个实体是名为Block的类。在Block类中,有一个函数,如果一个块在附近,它会返回,在这个函数中,我也会遍历实体的LinkedList,它是从Block中的以下tick方法调用的:
@Override
public void tick(float delta) {
if (color == Color.WHITE) {
if (getSurrounding(-32, -32) != null && getSurrounding(-32, -32).getColor() == Color.BLACK) {
if (getSurrounding(-32, -32).getStrength() < strength) {
getSurrounding(-32, -32).setStrength(-50);
}
}
}
if (!inGame.entities.isEmpty() && strength <= 0) {
inGame.entities.remove(this); // <------ REMOVING AN ELEMENT
}
}
public Block getSurrounding(int xOffset, int yOffset) {
for (Entity e : inGame.entities) {
if (e instanceof Block) {
if (x + xOffset == e.getX() && y + yOffset == e.getY()) {
return (Block) e;
}
}
}
return null;
}
(前两个代码示例位于InGame.java文件中,第36行是tick方法中的for循环)
现在如何停止此错误?通常与在循环中迭代列表时修改列表有关
我的假设是,在迭代过程中删除一个元素
为了防止这种情况发生,我建议在循环中(并且满足某些条件)保存要删除的对象,然后在循环完成后将其从列表中删除
编辑:根据更新的问题,您正在删除勾选方法中的元素。我不会在这里这样做,而是返回要删除的元素,并且仅当不再迭代要从中删除的列表时才将其删除
可能的解决方案:
我将创建另一个方法来检查实体的强度,并从tick方法调用该方法(这是为了保存tick方法,该方法必须返回要删除的对象),如下所示:
在实体类中:
public boolean checkStrength(){
if (!inGame.entities.isEmpty() && strength <= 0) {
return true;
}
return false;
}
public boolean checkStrength(){
if(!inGame.entities.isEmpty()&&strength通常与在循环中遍历列表时修改列表有关
我的假设是,在迭代过程中删除一个元素
为了防止这种情况发生,我建议在循环中(并且满足某些条件)保存要删除的对象,然后在循环完成后将其从列表中删除
编辑:根据更新的问题,您正在删除tick方法中的一个元素。我不会在这里执行此操作,而是返回您要删除的元素,并且仅当您不再迭代要从中删除的列表时才将其删除
可能的解决方案:
我将创建另一个方法来检查实体的强度,并从tick方法调用该方法(这是为了保存tick方法,该方法必须返回要删除的对象),如下所示:
在实体类中:
public boolean checkStrength(){
if (!inGame.entities.isEmpty() && strength <= 0) {
return true;
}
return false;
}
public boolean checkStrength(){
如果(!inGame.entities.isEmpty()&&strength您正在tick()
方法中删除实体…而在该方法中,您仍在外部tick方法中迭代实体…因为您正在修改e.tick()中的列表
,列表正在更改,这将导致下一次迭代失败…用内联方法替换对e.tick()
的方法调用将更清楚地说明问题:
@Override
public void tick(float delta) {
for (Entity e : entities) {
//e.tick(delta); --inline below
if (color == Color.WHITE) {
if (getSurrounding(-32, -32) != null && getSurrounding(-32, -32).getColor() == Color.BLACK) {
if (getSurrounding(-32, -32).getStrength() < strength) {
getSurrounding(-32, -32).setStrength(-50);
}
}
}
if (!inGame.entities.isEmpty() && strength <= 0) {
inGame.entities.remove(this); // <------ REMOVING AN ELEMENT
}
}
}
您正在删除tick()
方法中的实体…而在该方法中,您仍在迭代外部tick方法中的实体…因为您正在修改e.tick()
中的列表,列表正在更改,这会导致下一次迭代失败…替换对e.tick()的方法调用
使用内联方法可以更清楚地说明问题:
@Override
public void tick(float delta) {
for (Entity e : entities) {
//e.tick(delta); --inline below
if (color == Color.WHITE) {
if (getSurrounding(-32, -32) != null && getSurrounding(-32, -32).getColor() == Color.BLACK) {
if (getSurrounding(-32, -32).getStrength() < strength) {
getSurrounding(-32, -32).setStrength(-50);
}
}
}
if (!inGame.entities.isEmpty() && strength <= 0) {
inGame.entities.remove(this); // <------ REMOVING AN ELEMENT
}
}
}
使用迭代器的解决方案:
将第一个代码块替换为以下代码块:
public void tick(float delta) {
for (Iterator<Entity> iterator = entities.iterator(); iterator.hasNext();) {
boolean remove = e.tick(delta);
if(remove) {
iterator.remove();
}
}
player.tick(delta);
}
这应该可以解决您的问题。方法返回类型必须更改,以便我们有一个指示器,指示何时删除任何元素,何时不删除。每次勾选
返回true时,相应的元素将被删除使用迭代器的解决方案:
将第一个代码块替换为以下代码块:
public void tick(float delta) {
for (Iterator<Entity> iterator = entities.iterator(); iterator.hasNext();) {
boolean remove = e.tick(delta);
if(remove) {
iterator.remove();
}
}
player.tick(delta);
}
这应该可以解决您的问题。方法返回类型必须更改,以便我们有一个指示器,指示何时删除任何元素,何时不删除。每次勾选
返回true时,相应的元素将被删除在迭代时不要从列表中删除元素。@hellzone不完全为true。如果他使用迭代器
,它将work@hellzone海报似乎没有删除anything@hellzone我只是在迭代后删除块的tick方法中的元素,等等。所以这不是一个问题,对吗?显然是这样,否则你不会得到例外。在迭代元素时,不要从列表中删除元素。@hellzone这并不完全正确。如果他使用迭代器,它会work@hellzone海报似乎没有删除anything@hellzone我只是在迭代等之后删除块的tick方法中的元素,所以这不是一个问题,对吗?显然是的,否则你不会得到例外,或者只是使用Iterator
@XtremeBaumer我已经尝试了一个迭代器,但它不起作用,它给出了相同的错误。我现在添加了代码,实际上从LinkedList@XtremeBaumer我不清楚为什么你认为使用迭代器会有区别(我认为自己是一个有经验的java程序员).A for each循环有效地使用了一个迭代器“under the hood”不管怎样。我遗漏了什么吗?当你添加可能的解决方案时,它起作用了!非常感谢!或者只是使用一个迭代器@XtremeBaumer我已经尝试了一个迭代器,但它不起作用,它给出了相同的错误。我现在添加了代码,实际上从LinkedList@XtremeBaumer我不清楚你为什么认为使用ITror会有很大的不同(我认为自己是一个有经验的java程序员)。对于每个循环来说,不管怎样,都有效地使用了一个迭代器“在引擎盖下”。我是否缺少了一些东西?当你添加了可能的解决方案时,它就工作了!谢谢!
public void tick(float delta) {
for (Iterator<Entity> iterator = entities.iterator(); iterator.hasNext();) {
boolean remove = e.tick(delta);
if(remove) {
iterator.remove();
}
}
player.tick(delta);
}
public boolean tick(float delta) {
if (color == Color.WHITE) {
if (getSurrounding(-32, -32) != null && getSurrounding(-32, -32).getColor() == Color.BLACK) {
if (getSurrounding(-32, -32).getStrength() < strength) {
getSurrounding(-32, -32).setStrength(-50);
}
}
}
if (!inGame.entities.isEmpty() && strength <= 0) {
return true;
}
return false;
}