2009-01-15 145 views
36

我試圖編譯下面的代碼:如何在Java中使用foreach循環來循環訪問HashMap中的值?

private String dataToString(){ 
    Map data = (HashMap<MyClass.Key, String>) getData(); 
    String toString = ""; 
    for(MyClass.Key key: data.keySet()){ 
     toString += key.toString() + ": " + data.get(key); 
    return toString; 
} 

我得到一個錯誤的線路,說:

 
incompatible types 
found : java.lang.Object 
required: MyClass.Key 

getData()方法返回一個Object(但在這種情況下,Object返回具有HashMap結構)。 MyClass.Key是我爲我的應用程序創建的枚舉(在另一個類文件 - MyClass中)。

當我在MyClass.java中創建了一個具有相同結構的foreach循環時,我沒有遇到這個問題。

我在做什麼錯?

+0

當您要將它分配給Map時,不需要將getData()轉換爲HashMap。而是投它一個地圖。如果getData()返回一個非HashMap(如TreeMap)呢? – 2009-01-15 19:57:22

+0

我其實在這裏省略了一些信息... getData()實際上是getData(String key),其中key指定了我希望獲得的所需對象。所以,因爲我知道我得到的對象,所以我確切知道我應該如何處理它。 – troyal 2009-01-15 20:00:04

回答

42

稍微更有效的方式來做到這一點:

Map<MyClass.Key, String> data = (HashMap<MyClass.Key, String>) getData(); 
    StringBuffer sb = new StringBuffer(); 
    for (Map.Entry<MyClass.Key,String> entry : data.entrySet()) { 
     sb.append(entry.getKey()); 
     sb.append(": "); 
     sb.append(entry.getValue()); 
    } 
    return sb.toString(); 

如果可能的話,定義「的getData」所以你不需要演員。

38

變化:

Map data = (HashMap<MyClass.Key, String>) getData(); 

Map<MyClass.Key, String> data = (HashMap<MyClass.Key, String>) getData(); 

的問題是,如果data.keySet()數據僅僅是一個Map返回Collection<Object>。一旦你使它通用,keySet()將返回一個Collection<MyClass.Key>。更好的...遍歷entrySet(),這將是一個Collection<MyClass.Key, String>。它避免了額外的哈希查找。

+0

謝謝!你能解釋它爲什麼修復它嗎? – troyal 2009-01-15 19:34:20

+0

因爲您聲明它的方式Map數據聲明數據爲未知類型的Map,所以keySet()返回Object。進行更改告訴編譯器,密鑰是MyClass.Key,而不是Object。 – 2009-01-15 19:39:08

+0

當您將getData分配給Map數據時,您實際上將它分配給Map ,通過將其明確定義爲Map 數據,您可以讓foreach循環保留關鍵字是什麼類型的知識。 – 2009-01-15 19:39:21

3

Motlin的回答是正確的。

我有兩個音符......

  1. 不要使用toString += ...,但使用StringBuilder來代替,而將數據追加到它。

  2. 馬丁建議的演員將給你未經檢查的警告,你將無法擺脫,因爲它是非常不安全的。

的另一種方式,沒有警告(與StringBuilder的):

private String dataToString(){ 
    Map<?, ?> data = (Map<?, ?>) getData(); 
    StringBuilder toString = new StringBuilder(); 
    for (Object key: data.keySet()) { 
     toString.append(key.toString()); 
     toString.append(": "); 
     toString.append(data.get(key)); 
    } 
    return toString.toString(); 
} 

這工作,因爲toString方法就是你在key調用在Object類中定義的,所以你不需要在鑄造所有。

使用entrySet是更好的方法,因爲它不需要在地圖中執行另一個查找。

4

你可以抓住的entrySet代替,以避免需要重點班:

private String dataToString(){  
    Map data = (HashMap<MyClass.Key, String>) getData();  
    String toString = "";  
    for(Map.Entry entry: data.entrySet()) {   
     toString += entry.getKey() + ": " + entry.getValue(); 
    }  
    return toString; 
} 
5

我發現這個簡單的例子在java forum。它的語法與List的foreach非常相似,這正是我一直在尋找的。

import java.util.Map.Entry; 
HashMap nameAndAges = new HashMap<String, Integer>(); 
for (Entry<String, Integer> entry : nameAndAges.entrySet()) { 
     System.out.println("Name : " + entry.getKey() + " age " + entry.getValue()); 
} 

[編輯:]我測試了它,它完美的工作。