繁体   English   中英

尝试从ArrayList中删除元素

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM