37

我正在尝试编译以下代码:

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

我在 for 行中收到一条错误消息:

不兼容的类型
找到:java.lang.Object
必需:MyClass.Key

getData()方法返回一个Object(但在这种情况下,Object返回的具有HashMap结构)。 MyClass.Key是我为我的应用程序创建的一个枚举(在另一个类文件中 - MyClass)。

当我在 中创建具有相同结构的 foreach 循环时MyClass.java,我没有遇到这个问题。

我究竟做错了什么?

4

5 回答 5

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”,这样你就不需要演员表了。

于 2009-01-15T19:42:28.683 回答
38

改变:

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

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

问题是data.keySet()返回 a Collection<Object>if data 只是 a Map。一旦你使它通用,keySet()将返回一个Collection<MyClass.Key>. 更好...迭代entrySet(),这将是一个Collection<MyClass.Key, String>. 它避免了额外的哈希查找。

于 2009-01-15T19:32:43.603 回答
5

您可以改为获取 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;
}
于 2009-01-15T19:39:10.983 回答
5

我在java 论坛上找到了这个简单的例子。它的语法与我正在寻找的 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());
}

[编辑:]我测试了它,它工作得很好。

于 2011-04-19T21:40:19.783 回答
3

莫特林的回答是正确的。

我有两个笔记...

  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是更好的方法,因为它不需要在地图中进行另一次查找。

于 2009-01-15T19:38:57.397 回答