Java 从包含子类和超类项的arraylist中删除项

Java 从包含子类和超类项的arraylist中删除项,java,Java,我有一个arraylist“items”,其中包含来自超类的项以及来自其子类的项 for (Item item : items) { if (item.getLocation() == location) { System.out.println(item.getDescription() + " is in this location"); if (item instanceof Monste

我有一个arraylist“items”,其中包含来自超类的项以及来自其子类的项

    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);     
                }
            }   
        }   
    } 
如果发现怪物已经死亡,我将尝试从arraylist中删除该怪物。所有的方法都在工作,我知道在foreach循环中不能从arraylist中删除项,如上所示。我以前使用下面的代码从arraylist中删除怪物,但是这是在有单独的“项目”和“怪物”arraylist时。它们现在都在同一个'items'数组列表中,因为'Monster'类是'Item'类的子类

    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(); 
            }
        }
    }
Iterator iter=monsters.Iterator();
while(iter.hasNext())
{
怪物=iter.next();
if(monster.hasDied())
{
if(monster.getLocation()==位置)
{
System.out.println(monster.getDescription()+“已被击败!”);
iter.remove();
}
其他的
{
iter.remove();
}
}
}
我是否可以采用任何一种方法从arraylist中删除指定的怪物


谢谢你的帮助

绝对-您需要做的就是将现有的两种方法结合起来:

  • 使用
    Iterator
    迭代列表,方法与第二种方法相同
  • 按照您在第一种方法中的操作方式,检查当前
    项目是否为
    怪物。这种组合可以让您找到
    怪物
    ,并使用迭代器将其删除
以下是如何做到这一点:

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(); 
            }
        }
    }
}
Iterator iter=items.Iterator();
while(iter.hasNext())
{
Item=iter.next();
如果(怪物的物品实例)
{
怪物=(怪物)物品;
if(monster.hasDied())
{
if(monster.getLocation()==位置)
{
System.out.println(monster.getDescription()+“已被击败!”);
iter.remove();
}
其他的
{
iter.remove();
}
}
}
}

绝对-您需要做的就是将现有的两种方法结合起来:

  • 使用
    Iterator
    迭代列表,方法与第二种方法相同
  • 按照您在第一种方法中的操作方式,检查当前
    项目是否为
    怪物。这种组合可以让您找到
    怪物
    ,并使用迭代器将其删除
以下是如何做到这一点:

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(); 
            }
        }
    }
}
Iterator iter=items.Iterator();
while(iter.hasNext())
{
Item=iter.next();
如果(怪物的物品实例)
{
怪物=(怪物)物品;
if(monster.hasDied())
{
if(monster.getLocation()==位置)
{
System.out.println(monster.getDescription()+“已被击败!”);
iter.remove();
}
其他的
{
iter.remove();
}
}
}
}

正如您所知,在迭代集合时无法删除项。因此,您可以创建一个列表(称之为toRemoveObjList),列出您在迭代和检查状态时要删除的对象。完成迭代后,应该有一个需要删除的所有对象的列表。然后简单地打电话

list.removeAll(toRemoveObjList);
供您参考,javadocs For removeAll(集合c)


正如您所知,在迭代集合时无法删除项。因此,您可以创建一个列表(称之为toRemoveObjList),列出您在迭代和检查状态时要删除的对象。完成迭代后,应该有一个需要删除的所有对象的列表。然后简单地打电话

list.removeAll(toRemoveObjList);
供您参考,javadocs For removeAll(集合c)


我不确定你想要实现什么,但为什么你不简单地这样写:

    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();
                    }
            }
     }
for(Iterator iter=items.Iterator();iter.hasNext();){
Item=iter.next();
如果(怪物的物品实例){
怪物=(怪物)物品;
if(monster.hasDied()){
if(monster.getLocation()==位置){
System.out.println(monster.getDescription()+“已被击败!”);
}
iter.remove();
}
}
}

我不确定您想要实现什么,但为什么不简单地这样写:

    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();
                    }
            }
     }
for(Iterator iter=items.Iterator();iter.hasNext();){
Item=iter.next();
如果(怪物的物品实例){
怪物=(怪物)物品;
if(monster.hasDied()){
if(monster.getLocation()==位置){
System.out.println(monster.getDescription()+“已被击败!”);
}
iter.remove();
}
}
}

避免类型检查的多态方法如下所示。在这种方法中,特定的
项目
是否是
怪物
并不重要,因为可以检查所有
项目
的有效性,并且
项目
本身知道它在无效时会做什么

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
    }
}


这特别好,因为当其他
项目
s(例如只有一定数量用途的药剂(
药剂扩展项目
)也可能无效时,它可以很好地扩展。

避免类型检查的多态方法如下所示。在这种方法中,特定的
项目
是否是
怪物
并不重要,因为可以检查所有
项目
s