Java ArrayList:使用字符串名称添加对象

时间:2013-02-12 16:16:17

标签: java string for-loop arraylist

这是一项非常简单的任务,但我觉得我忽视了一些事情。我有多个对象,我正在尝试添加到ArrayList,并且每个对象都有一个String形式的标识名称。我需要通过调用字符串名称来查找(交互)ArrayList中的对象。所以我尝试了这个:

在我的项目课中,我有:     private String itemName;

public Item(String name)
{
    itemName = name;
}

所以我可以给它一个名称供用户使用。


然后在我与该对象交互的类中,我创建了一个ArrayList:

private ArrayList<Item> items = new ArrayList<Item>();

我首先通过它的实际对象名称向arrayList添加一个对象,但是我需要能够使用它的String名称与它进行交互,所以我尝试了这个:

public void removeItem(String itemName)
{
    for (int i = 0; i < items.size(); i++)
    {
        if (items.get(i).toString() == itemName)
        {
            items.remove(i);
        }
        break;
    }

}

但它并没有删除该项目。如果所有这一切都令人困惑,本质上我正在尝试创建一个OBJECT,我可以给出一个STRING名称(就像我对上面的项目所做的那样),然后能够将OBJECT添加到ArrayList,然后最终成为能够通过调用STRING名称删除,获取或对ArrayList中的OBJECTS执行某些操作。我知道我需要迭代ArrayList,但我实际上无法获得该对象。

感谢您的帮助。

5 个答案:

答案 0 :(得分:4)

你在这里犯了三个错误:

  • 您正在使用的items.get(i).toString()不会为itemName提供Item。它只会为您提供Item类的字符串表示形式,如果您不重写,则由Object类的toString方法返回。但是,如果您覆盖toString方法并从中返回itemName,则可能会有效。但是,我没有看到。即使您已覆盖它,我建议您为itemName字段添加 getter setter ,然后使用该字段返回itemName

  • 您正在使用==运算符比较字符串,这不会给您正确的结果。您应该始终使用equals方法比较字符串。

因此,您的if statement应如下所示:

 if (items.get(i).getName().equals(itemName))
  • 第三个问题是,您正在尝试修改您正在迭代的List。这不会有效,可能会抛出ConcurrentModificationException。在迭代时,您应该使用IteratorList中删除元素。

有关这两个问题的详细信息,请参阅

此外,您可以考虑在equals中覆盖class方法,然后使用equals方法直接比较您的实例。


现在,已经用你的代码指出了一些逻辑问题,现在是时候指出一些设计问题了。

根据您的要求,您似乎需要使用HashMap,而不是存储属性的某些自定义类型List。您可以像这样创建map

Map<String, Integer> map = new HashMap<String, Integer>();

将包含itemName到相应Item的映射,然后获取特定itemName的Item就像map.get(itemName)一样简单。

答案 1 :(得分:3)

听起来你应该使用Map,例如java.util.HashMap<String, Item>Map接口提供了您正在寻找的那些操作,并且它也是可迭代的。

答案 2 :(得分:1)

在对象中添加一个getter来获取名称,如下所示:

public class Item {
   private final String name; //once given cannot change
   public Item(String name) {
      this.name = name; //yhis.name to distinguish between 2 variabled both called "name"
   }
   public String getName() {
      return name; //this.name not required as no other variable called "name" is in scope
   }
}

然后你可以找到你的项目:

for (Item item : theList) {
   if (item.getName.equals(requiredName)) {
      //got you!
   }
}

一般来说,不要将字符串与==进行比较。另外,如果你想从迭代的列表中删除一个项目,你必须使用(较旧的)迭代器语法:

Iterator<Item> iter = theList.iterator();
while (iter.hasNext()) {
   Item item = iter.next();
   if (item.getName.equals(requiredName)) {
      //got you!
      iter.remove();
      break; //no need to go over the rest of the list
   }
}

最后,如果您只想按名称查找项目,则列表不是您最好的集合,因为找到该项目可能需要遍历整个列表。 map(特别是hashmap)将为这种类型的操作提供更好的性能。你可以使用名称作为关键

答案 3 :(得分:0)

我的猜测是你的items.get(i).toString()没有做你想象的那样。为什么不使用items.get(i).name或在Item对象中为name创建getter或setter,并按items.get(i).getName()

检索名称

答案 4 :(得分:0)

有这个 - 你实现removeItem的方式,你也可以直接使用它 ArrayList.remove(item.itemName) - 就在你让所有人坚持ConcurrentModificationException并重新实现已经存在的东西之前 - 看看图书馆!阅读ArrayList的文档!

为了澄清:在Java中(并且主要仅在Java中):==表示引用的比较。

所以:

String a = "A";
String b = new StringBuilder("A").toString();
if (a == b) // --> false
if (a.equals(b)) // --> true

您还可以考虑使用org.apache.commons.lang.StringUtils.equals - 这对于空指针是安全的。

正如其他人已经指出的那样 - toString - 方法只有在你正确实现它时才能正常工作(在你的情况下返回名字)。原始toString返回一个类名和一个ID。这可能不是你想要的(只是试着打印出来)。