我有一个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);
}
}
}
}
如果发现怪物已经死亡,我试图从怪物中移除怪物。所有这些方法都有效,我知道你在foreach循环中不能从arraylist中删除项目,如上所示。我以前使用下面的代码从arraylist中删除怪物,但是当有一个单独的'items'和'monsters'arraylist时。它们现在都在相同的'items'arraylist中,因为'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();
}
}
}
无论如何我可以采用任何一种方法从arraylist中移除指定的怪物吗?
感谢您的帮助!
答案 0 :(得分:3)
绝对 - 您需要做的就是结合您拥有的两种方法:
Iterator
按照第二种方法中的方式迭代列表; item
的方式Monster
。这个组合可以让你使用迭代器找到它Monster
和remove
。以下是如何做到这一点:
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();
}
}
}
}
答案 1 :(得分:1)
避免类型检查的多态方法如下。在此方法中,特定Item
是否为Monster
并不重要,因为可以检查所有Item
的有效性,Item
本身知道它是如何做的无效
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";
}
}
由于可以检查所有项目的有效性,因此特定Item
是Monster
Iterator<Item> iter = items.iterator();
while (iter.hasNext())
{
Item item = iter.next();
if (item.isStillValid()==false)
{
System.out.println(item.getNoLongerValidText());
iter.remove();
}
}
这是特别好的,因为当其他Item
(例如只有一定数量用途的药水(Potion extends Item
)也可能无效时,它可以很好地扩展。
答案 2 :(得分:0)
如您所知,在迭代集合时无法删除项目。因此,您可以做的是在迭代和检查其状态时创建要删除的对象的列表(让它调用toRemoveObjList)。完成迭代后,您应该有一个需要删除的所有对象的列表。然后简单地调用
list.removeAll(toRemoveObjList);
供参考,javadocs for removeAll(Collection c)
答案 3 :(得分: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();
}
}
}