这是一项非常简单的任务,但我觉得我忽视了一些事情。我有多个对象,我正在尝试添加到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,但我实际上无法获得该对象。
感谢您的帮助。
答案 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
。在迭代时,您应该使用Iterator
从List
中删除元素。有关这两个问题的详细信息,请参阅
此外,您可以考虑在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。这可能不是你想要的(只是试着打印出来)。