2009-01-15 146 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()); 
} 

[编辑:]我测试了它,它完美的工作。