简体   繁体   English

尝试从ArrayList中删除元素

[英]Attempting to remove element from ArrayList

I'm attempting to create a class which will display text for a couple of seconds and then disappear. 我正在尝试创建一个类,该类将显示文本几秒钟,然后消失。

I'm using LWJGL and in my main class MetalCLicker i have a for loop which cycles through the popups. 我正在使用LWJGL,在我的主类MetalCLicker中,我有一个for循环,该循环循环弹出窗口。

            for(PopUp pop: popups){
            pop.tick(pop);
        }

popup class: (problem at bottom in tick method) public class PopUp { 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();
}
}

The program crashes when lifetime hits 0, thus attempting to remove the element. 生命周期为0时,程序崩溃,因此尝试删除该元素。 Putting prints before and after the remove line successfully prints out the line, So I'm confused now :( 在删除行之前和之后都成功地打印出行,所以我现在很困惑:(

I have tried using this in the tick method so i switched to sending the actual element in the parameter. 我尝试在tick方法中使用此方法,因此我切换为在参数中发送实际元素。

There is no error in the console, but the debug tells me ArrayList$Itr.next() line: 831 ArrayList$Itr.checkForComodification() line: 859 [local variables unavailable] 控制台中没有错误,但是调试告诉我ArrayList $ Itr.next()行:831 ArrayList $ Itr.checkForComodification()行:859 [本地变量不可用]

inside Thread [main] 内部线程[main]

I'll update post with more info if needed, but i cant think of what to say to help you, help me. 如果需要,我会用更多信息来更新帖子,但是我想不出该说些什么来帮助您,帮助我。

And info on how i can go about without using MetalCLicker game in my method parameters would be cool. 而且有关如何在我的方法参数中不使用MetalCLicker游戏的情况下进行操作的信息很酷。

you're trying to remove elements while iterating through the list, thus invalidating the iterator. 您尝试在遍历列表时删除元素,从而使迭代器无效。 You cannot use this: 您不能使用此:

for(PopUp pop: popups) {
  popups.remove(pop); // effectively, due to tick
}

or even, safely, this: 甚至安全地:

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
}

However, you CAN use this: 但是,您可以使用以下命令:

for(var i=popups.size()-1; i>=0; i--) {
  PopUp pop = popups.get(i);
  popups.remove(pop);
}

because any removals now happen in the part of the array list that will not be touched by the next iteration 因为现在所有删除都发生在数组列表的一部分中,下次迭代不会涉及

You can't loop around a collection and remove an item directly from it at the same time. 您不能在一个集合周围循环并同时直接从其中删除一个项目。 You have two options here, you can copy this collection to a new collection for the loop alone or you can, instead of using a foreach , use the collection iterator directly and send the iterator as a parameter to the tick method, then you can call the remove method at the collection iterator and it won't throw this exception. 您在此处有两个选择,您可以将此集合单独复制到循环的新集合中,也可以不使用foreach ,而直接使用集合迭代器并将迭代器作为参数发送给tick方法,然后可以调用集合迭代器上的remove方法,它不会引发此异常。

So it's either change the foreach to: 因此,可以将foreach更改为:

for(PopUp pop : popups.clone()){
    pop.tick(pop);
}

Or use an iterator instead of a foreach: 或使用迭代器代替foreach:

Iterator<PopUp> iterator = popups.iterator();
while ( iterator.hasNext() ) {
  PopUp pop = iterator.next();
  pop.tick(iterator);
}

And at the tick implementation: tick实现中:

public void tick(Iterator it){
    y -= 3/lifetime;

    lifetime -= 1;
    if (lifetime == 0) {
      it.remove();
    }
    else render();
}

Both have mostly the same effect, but I'd say the second option is better. 两者的效果大致相同,但我想说第二种选择更好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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