2

我有一个数组列表“项目”,其中包含来自超类的项目以及来自其子类的项目。

    for (Item item : items)
    {
        if (item.getLocation() == location)
        {   
            System.out.println(item.getDescription() + " is in this location");
            if (item instanceof Monster)
            {
                Monster monster = (Monster)item; 
                if (monster.hasDied())
                {
                    System.out.println(monster.getDescription() + " has been defeated!");
                    items.remove(monster);     
                }
            }   
        }   
    } 

如果发现怪物已经死亡,我正在尝试从数组列表中删除怪物。所有方法都有效,我知道您不能在如上所示的 foreach 循环中从数组列表中删除项目。我以前使用下面的代码从数组列表中删除怪物,但是这是当有一个单独的“项目”和“怪物”数组列表时。它们现在都在同一个“项目”数组列表中,因为“怪物”类是“项目”类的子类。

    Iterator<Monster> iter = monsters.iterator();
    while (iter.hasNext()) 
    {
        Monster monster = iter.next();
        if (monster.hasDied())
        {
            if (monster.getLocation() == location)
            {
                System.out.println(monster.getDescription() + " has been defeated!");
                iter.remove();
            }
            else
            {
               iter.remove(); 
            }
        }
    }

无论如何我可以采用任何一种方法从数组列表中删除指定的怪物吗?

谢谢你的帮助!

4

4 回答 4

3

绝对 - 您需要做的就是结合您拥有的两种方法:

  • Iterator使用第二种方法中的方式迭代列表;
  • 检查当前item是否是Monster您在第一种方法中执行的方式。这种组合可以让你找到Monster, 和removeit 使用迭代器。

您可以这样做:

Iterator<Item> iter = items.iterator();
while (iter.hasNext()) 
{
    Item item = iter.next();
    if (item instanceof Monster)
    {
        Monster monster = (Monster)item; 
        if (monster.hasDied())
        {
            if (monster.getLocation() == location)
            {
                System.out.println(monster.getDescription() + " has been defeated!");
                iter.remove();
            }
            else
            {
               iter.remove(); 
            }
        }
    }
}
于 2013-07-04T09:41:20.313 回答
1

避免类型检查的多态方法如下。Item在这种方法中,一个特定的是否是 a无关紧要,因为可以检查Monster所有s 的有效性,并且如果它无效,它本身知道它会做什么ItemItem

public class Item {
    //assorted item methods


    public boolean isStillValid(){
        return true; //by default items remain valid
    }

    public String getDescription(){
        return "SomeItem"; //I assume you can provide a better description than this, I don't know your usage case so can't comment
    }

    public String getNoLongerValidText(){
        return getDescription() + "is no longer valid"; //items that actually become invalid should override this and give a better text
    }
}


public class Monster extends Item{

    //assorted extra Monster Methods

    int health=100;

    public boolean isStillAlive(){
        if (health<=0){
            return false;
        }else{
            return true;
        }
    }

    @Override
    public boolean isStillValid() {
        return isStillAlive();
    }

    @Override
    public String getDescription() {
        return "MonsterName";
    }

    @Override
    public String getNoLongerValidText() {
        return getDescription() + "has died";
    }

}

因为可以检查所有项目的有效性,所以如果一个特定的项目ItemMonster

Iterator<Item> iter = items.iterator();
while (iter.hasNext()) 
{
    Item item = iter.next();
    if (item.isStillValid()==false)
    {
        System.out.println(item.getNoLongerValidText());
        iter.remove();
    }
}

这特别好,因为当其他Items(例如Potion extends Item,只有一定数量的使用次数的 potion ( ))也可能变得无效时,它可以很好地扩展。

于 2013-07-04T10:04:36.453 回答
0

如您所知,您无法在迭代集合时删除项目。所以你可以做的是创建一个列表(我们称之为 toRemoveObjList),在迭代和检查它们的状态时要删除的对象。完成迭代后,您应该有一个需要删除的所有对象的列表。然后只需调用

list.removeAll(toRemoveObjList);

供您参考,removeAll(Collection c) 的 javadocs

http://docs.oracle.com/javase/6/docs/api/java/util/AbstractCollection.html#removeAll(java.util.Collection)

于 2013-07-04T09:42:47.863 回答
0

我不确定您要达到什么目的,但是为什么您不会简单地这样写:

    for (Iterator<Item> iter = items.iterator(); iter.hasNext();) {
            Item item = iter.next();
            if (item instanceof Monster) {
                    Monster monster = (Monster) item;
                    if (monster.hasDied()) {
                        if (monster.getLocation() == location) {
                            System.out.println(monster.getDescription() + " has been defeated!");
                        }
                        iter.remove();
                    }
            }
     }
于 2013-07-04T09:47:49.347 回答