【问题标题】:Search through arraylist, remove item from arraylist, add it elsewhere通过arraylist搜索,从arraylist中删除项目,将其添加到其他地方
【发布时间】:2014-11-28 17:53:18
【问题描述】:

public void drop (String name) - 如果合适,从 ArrayList 中删除该项目并将其添加到当前房间。使用以下选项之一更新游戏消息:1) 玩家没有持有该物品,2) 房间已有物品,或 3) 玩家已成功将物品放入房间。这是此方法的目标,但是当我运行它时,它总是跳到 else 语句中的 currentMessage。

问题: 我遇到的问题是,当我运行此方法并尝试将项目放入房间时,它不会跳到 else 语句并返回消息“您没有该项目”,我不知道为什么正在这样做并且没有通过第一个 if 语句,因为我正在输入一个我知道在 arraylist 中的项目名称。

public void drop(String name)
{      
    for(Item count : myArray){
        if(count.getName().contains(name) && currentRoom.hasItem() == false){
            currentRoom.addItem(count);
            currentMessage = "you have successfully dropped the item in the room";
            myArray.remove(count);
        }
        else if(count.getName().contains(name) && currentRoom.hasItem() == true)
        {
            currentMessage = "the room already has an item";
        }
        else 
        {
            currentMessage = "you do not have that item";
        }
    }
}

【问题讨论】:

  • 那么究竟是什么问题?

标签: java arraylist


【解决方案1】:

这将引发ConcurrentModificationException,因为在修改列表时不能使用foreach 循环。相反,迭代器支持 Iterator.remove() 方法,该方法允许您从基础集合中删除对象:

public void drop(String name)
{   
    Iterator<Item> it = myArray.iterator();
    Item count = it.next();
    while(count != null){
        if(count.getName().contains(name) && currentRoom.hasItem() == false){
            currentRoom.addItem(count);
            currentMessage = "you have successfully dropped the item in the room";
            it.remove();
        }
        else if(count.getName().contains(name) && currentRoom.hasItem() == true)
        {
            currentMessage = "the room already has an item";
        }
        else 
        {
            currentMessage = "you do not have that item";
        }
        count = it.next();
    }
}

【讨论】:

  • 此代码可以简化:while ((count = it.next()) != null)
  • @AlexWien 但是上面的代码也可以在一个 do-while 中打开,这样你只需要一个 count = ... 语句而不是两个 - 我的 while 循环的问题在哪里?我相信它会起作用的......
  • @msrd0 这不是一个语句,在您的改进提示和他的两个解决方案中,条件都需要两个语句。你只写了一行。这不会保存任何内容。
【解决方案2】:

您的问题是您在迭代时不允许编辑数组。像这样更改您的 for 循环以消除错误。您也错误地使用了 if 循环。不要要求完整的条件为假,而只要求您希望为假的条件,并在其前写上!

public void drop(String name)
{      
    for (int i = 0; i < myArray.size(); i++) {
        Item count = myArray.get(i);
        if (count.getName().contains(name) && !currentRoom.hasItem()){
            currentRoom.addItem(count);
            currentMessage = "you have successfully dropped the item in the room";
            myArray.remove(count);
            i--; // element removed, so decrease count
        }
        else if(count.getName().contains(name) && currentRoom.hasItem() == true)
        {
            currentMessage = "the room already has an item";
        }
        else 
        {
            currentMessage = "you do not have that item";
        }
    }
}

【讨论】:

  • @ChrisThompson OP 会为他的代码获得 java.util.ConcurrentModificationException
  • @Christopher 那么请接受我的回答,以便以后的访客知道问题已解决
  • 嘿,很抱歉重复了,我在发布之前没有看到你的答案。已经删除了。
  • @msrd0 你的答案不是最简单的方法。
  • 在这个答案和 OP 的原始解决方案中,设置的任何“currentMessage”都将在最后一次迭代中被“你没有那个项目”重置,除非你正在寻找的项目是最后一个。这似乎有点违反直觉。
【解决方案3】:

试试这个;

public void drop(String name)
{
    for (Iterator<Item> it = col.iterator(); it.hasNext();)
    {
        Item count = it.next();
        if(count.getName().contains(name))
        {
            if(currentRoom.hasItem() == false)
            {
               currentRoom.addItem(count);
               currentMessage = "you have successfully dropped the item in the room";
               it.remove();
               return; //Once found return;
            }
            else
            {
               currentMessage = "the room already has an item";
               return; //Once found return or alternatively keep looking
            }
        }           
    }
    //Item never found
    currentMessage = "you do not have that item";       
}

除了 ConcurrentModificationException 之外,您的代码还有一个逻辑缺陷,它会在每次迭代后设置消息,而您可能希望它在设置 currentMessage 之前查看整个列表。

【讨论】:

  • OP 不一定要返回,continue 会更好
  • 根据他的问题,只有当前房间应该被操作,所以我假设对列表的迭代只是为了“找到”当前房间,而不是处理所有房间。
猜你喜欢
  • 1970-01-01
  • 2015-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多