2013-02-12 102 views
-3

這是一個非常簡單的任務,但我覺得我忽略了一些東西。我有多個對象,我試圖將其添加到一個ArrayList中,並且每個對象都有一個String形式的標識名稱。我需要能夠通過調用字符串名稱來查找(交互)ArrayList中的對象。所以我試過這個:Java ArrayList:使用字符串名稱添加對象

在我的項目類中我有: private String itemName;

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

所以我可以給它一個名字供用戶使用。


然後在我的類與對象進行交互,我創建了一個ArrayList:

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

我第一個對象添加到ArrayList由它的實際對象的名字,但我需要能夠使用它的字符串名稱與它交互,所以我試過這個:

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,但我實際上無法獲得該對象。

感謝您的任何幫助。

回答

4

您是東三大誤區這裏:

  • 您正在使用items.get(i).toString()這不會給你itemNameItem。它只會給你一個Item類的字符串表示形式,如果你沒有重載一個,則返回Object類的toString方法。但是,如果您已覆蓋toString方法並從中返回itemName,則此方法可能有效。但是,我看不到。即使你已經覆蓋,我建議你有獲得者設置器您的itemName字段,並使用它返回itemName

  • 您正在使用==運算符比較字符串,這不會給您正確的結果。您應該始終使用equals方法比較字符串。

所以,你if statement應該是這樣的:

if (items.get(i).getName().equals(itemName)) 
  • 第三問題是,您要修改,你是在迭代List。這不會奏效,並且可能會拋出ConcurrentModificationException。迭代時,您應該使用IteratorList中刪除元素。

詳情參見關於這兩個問題,以及如何解決這些問題:

此外,可以考慮覆蓋在equals方法你class,然後你可以使用直接比較你的實例方法。現在


,已經指出了一些邏輯問題與您的代碼,它的時間來指出一些設計問題

根據您的要求,您似乎需要使用HashMap,而不是某個存儲屬性的自定義類型的List。您可以創建一個map這樣的:

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

其中將包含itemName映射到相應的Item,然後獲得Item特定ITEMNAME是map.get(itemName)一樣簡單。

+0

感謝您的幫助。雖然我更喜歡使用HashMap,就像你所建議的那樣,但是對於這一小部分代碼的要求是必須使用ArrayList。 – 2013-02-12 19:08:12

+0

@JordanPlahn。抱歉。讀'while'爲'why'錯誤。 – 2013-02-12 19:10:29

0

我的猜測是,你items.get(I)的ToString()不會做你認爲它。你爲什麼不使用某些東西一樣items.get(I)。名稱或項目對象創建名稱的getter和setter方法和items.get(I).getName()獲取名稱

1

吸氣劑添加到您的對象獲取的名字,像這樣:

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 
    } 
} 

;最後,如果你想要的是他們的名字列表來查找物品因爲找到該項目可能需要遍歷整個列表,因此這不是您最好的收集。地圖(專門用於HashMap)將爲您提供更好的性能,適用於此類操作。您可以使用該名稱作爲密鑰

3

聽起來像您應該使用Map來做這件事,例如java.util.HashMap<String, Item>Map接口提供了您正在查找的那些操作,也是可迭代的。

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。這可能不是你想要的(只是試圖打印出來)。

相關問題