从玩家的背包中移除物品

后端开发 2026-07-10

游戏中有一个修复任务。
有一个所需物品的清单。当方法被调用时,它会遍历背包,如果发现匹配项,就把物品加入到名为 "toRemove" 的清单中;循环结束后,再把这些物品从玩家的背包以及必需物品清单中移除。如果我没看错的话,这在只有一个物品的情况下是可行的。现在我不知道如何处理重复项的情况。在这个实现中,它会删除requiredItems中同名的所有物品(也可能从玩家背包中一并删除)。

public boolean tryRepair(List<Item> inventory) {
    List<Item> toRemove = new ArrayList<>();

    for (Item item : inventory) {
        for (RepairItem required : requiredItems) {
            if (item.getName().equals(required.getName())) {
            toRemove.add(item);
            repairedItems.add(required);
            break;
            }
        }
    }

    inventory.removeAll(toRemove);
    requiredItems.removeAll(toRemove);

    if (repairedItems.size() < requiredItems.size()) {
        completed = false;
    } else {
        completed = true;
    }
    return true;
}

现在我该采用什么方法来处理重复项?

** 新增了Item类

public abstract class Item {
   private String name;
   private String description;

    public Item(String name, String description) {
        this.name = name;
        this.description = description;
    }

    public String getName() {
        return name;
    }

    public String getDescription() {
        return description;
    }

}

解决方案

removeAll() 将根据 equals() 方法移除所有匹配的对象。因此,当你的列表中存在相同的对象(按 equals())且你使用 removeAll() 传入一个“等于”其中一个对象的对象时,它们都会被删除。

你也可以使用 remove(Object) 仅移除与给定对象匹配的一个对象,基于 equals() 方法。请参阅文档:

boolean remove(Object o)

从此集合中移除指定元素的一个实例(如果存在)(可选操作)。 [...]

(emphasis mine)

一个简单的 "foreach" 循环 就能解决:

for (Item item : toRemove) {
    inventory.remove(item);     // removes only one
    requiredItems.remove(item); // removes only one
}

备选方案

解决方案很简单:你只需要颠倒循环的顺序(这也解释了“break”的存在,它可以防止不必要的删除)。在此基础上,我们再看看如何实现它,以减少代码量并提高性能(尽管实际效果可能不明显)。

public boolean tryRepair( List<Item> inventory ) {

      // To avoid creating new lists in order to remove the corresponding
      // items, we iterate through the lists in reverse order; this way,
      // we can remove the items “on the fly”
    for( int i = required.length - 1; i-- >= 0; ) { 
        for( int k = inventory.length - 1; k-- >= 0; ) { 
            if( inventory[ k ].getName().equals( required[ i ].getName() )) {
                inventory.remove( k );
                repairedItems.add( required.remove( i ) );
                break;
            }
        }
    }

      // these lines don't seem to make much sense; perhaps it's a typo,
      // and the last line should be: “return completed;”
    if( repairedItems.size() < requiredItems.size() ) {
        completed = false;
    } 
    else {
        completed = true;
    }
    return true;
}

问题:类 Item 的对象是否与类 RepairItem 的对象不同,以至于存在类 RepairItem 的合理性?或者是否可以通过使用两个名称合适的 Item 列表来避免这种情况?

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章