[英]Attempting to remove element from ArrayList
我正在尝试创建一个类,该类将显示文本几秒钟,然后消失。
我正在使用LWJGL,在我的主类MetalCLicker中,我有一个for循环,该循环循环弹出窗口。
for(PopUp pop: popups){
pop.tick(pop);
}
popup类:(刻度方法底部的问题)public class PopUp {
MetalClicker game;
int x;
float y, lifetime;
String line1, line2, line3;
Color color;
private UnicodeFont font;
public PopUp(MetalClicker game, int x, int y, float lifetime, String line1, String line2, String line3, Color color){
this.x = x;
this.y = y;
this.lifetime = lifetime*game.fps;
this.line1 = line1;
this.line2 = line2;
this.line3 = line3;
this.color = color;
this.game = game;
font = new UnicodeFont(new java.awt.Font ("Vani", Font.BOLD, 12));
font.getEffects().add(new ColorEffect(java.awt.Color.white));
font.addNeheGlyphs();
try {
font.loadGlyphs();
} catch (SlickException e) {
e.printStackTrace();
}
}
public void render(){
font.drawString(x - (line1.length()/2), y, line1, color);
font.drawString(x - (line2.length()/2), y+14, line2, color);
font.drawString(x - (line3.length()/2), y+28, line3, color);
}
public void tick(PopUp pop){
y -= 3/lifetime;
lifetime -= 1;
if (lifetime == 0) game.popups.remove(pop); //problem resides here
else render();
}
}
生命周期为0时,程序崩溃,因此尝试删除该元素。 在删除行之前和之后都成功地打印出行,所以我现在很困惑:(
我尝试在tick方法中使用此方法,因此我切换为在参数中发送实际元素。
控制台中没有错误,但是调试告诉我ArrayList $ Itr.next()行:831 ArrayList $ Itr.checkForComodification()行:859 [本地变量不可用]
内部线程[main]
如果需要,我会用更多信息来更新帖子,但是我想不出该说些什么来帮助您,帮助我。
而且有关如何在我的方法参数中不使用MetalCLicker游戏的情况下进行操作的信息很酷。
您尝试在遍历列表时删除元素,从而使迭代器无效。 您不能使用此:
for(PopUp pop: popups) {
popups.remove(pop); // effectively, due to tick
}
甚至安全地:
for(var i=0, last=popups.size(); i<last; i++) {
PopUp pop = popups.get(i);
popups.remove(pop); // next "i++" will skip over an item
}
但是,您可以使用以下命令:
for(var i=popups.size()-1; i>=0; i--) {
PopUp pop = popups.get(i);
popups.remove(pop);
}
因为现在所有删除都发生在数组列表的一部分中,下次迭代不会涉及
您不能在一个集合周围循环并同时直接从其中删除一个项目。 您在此处有两个选择,您可以将此集合单独复制到循环的新集合中,也可以不使用foreach
,而直接使用集合迭代器并将迭代器作为参数发送给tick
方法,然后可以调用集合迭代器上的remove方法,它不会引发此异常。
因此,可以将foreach
更改为:
for(PopUp pop : popups.clone()){
pop.tick(pop);
}
或使用迭代器代替foreach:
Iterator<PopUp> iterator = popups.iterator();
while ( iterator.hasNext() ) {
PopUp pop = iterator.next();
pop.tick(iterator);
}
在tick
实现中:
public void tick(Iterator it){
y -= 3/lifetime;
lifetime -= 1;
if (lifetime == 0) {
it.remove();
}
else render();
}
两者的效果大致相同,但我想说第二种选择更好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.