我需要遍历地图的入口集,我不知道它的参数化类型。
当迭代这样的入口集时,为什么这不能编译?
public void myMethod(Map anyMap) {
for(Entry entry : anyMap.entrySet()) {
...
}
}
但是这个编译:
public void myMethod(Map anyMap) {
Set<Entry> entries = anyMap.entrySet();
for(Entry entry : entries) {
...
}
}
这也编译(我不能使用这个,因为我不知道地图的类型):
public void myMethod(Map<String, String> stringMap) {
for(Entry<String,String> entry : stringMap.entrySet()) {
...
}
}
答案 0 :(得分:23)
你在第一个错误中得到的错误是:
Type mismatch: cannot convert from element type Object to Map.Entry
这是因为编译器会转换FOR-IN循环:
for (Entry entry : anyMap.entrySet()) {
}
要:
for (Iterator i = anyMap.entrySet().iterator(); i.hasNext();) {
Entry e = i.next(); // not allowed
}
您的第二个示例有效,但仅限于作弊!您正在进行未经检查的演员,以便将Set
返回变为Set<Entry>
。< / p>
Set<Entry> entries = anyMap.entrySet(); // you get a compiler warning here
for (Entry entry : entries) {
}
变为:
Set<Entry> entries = anyMap.entrySet();
for (Iterator<Entry> i = entries.iterator(); i.hasNext(); ) {
Entry e = (Entry) i.next(); // allowed
}
<强>更新强>
正如评论中所提到的,两个示例中的类型信息都会丢失:因为编译器的原始类型擦除规则。
为了提供向后兼容性,原始类型实例的所有方法将被其擦除对应方替换。因此,因为您的Map
是原始类型,所有内容都会被删除。包括其Set<Map.Entry<K, V>> entrySet();
方法:您的原始类型实例将被强制使用已删除的版本:Set entrySet()
。
答案 1 :(得分:6)
这是因为你使用原始类型Map,因此map.entrySet()会获得一个非参数化的Set,它反过来在迭代时产生Object,而不是Entry。
一个简单但优雅的解决方案是使用Map&lt;?,?&gt;,它仍然允许您传递任何Map,但另一方面强制map.entrySet()返回值Set&lt; Entry&gt ;:
public void test(Map<?,?> map) {
for(Entry e : map.entrySet()){
Object key = e.getKey();
Object value = e.getValue();
}
}
答案 2 :(得分:2)
在第一个示例中,map.entrySet()返回Set,当您循环迭代时,使用Iterator。没有关于设置内容类型的信息,因此Java使用Object as Object是基类型,编译器告诉您它不能将Object转换为Entry。
Set<Map.Entry<K, V>> entrySet();
使用原始地图类型时,entrySet仅返回Set,没有类型信息。
在第二个示例中,您手动将Set转换为Set&lt; Entry&gt; (有警告)。现在Java知道里面是什么。所以你可以迭代。
在上一个示例中,您知道地图类型,因此entrySet返回正确的类型集,您可以在没有任何类型约定的情况下进行迭代。
答案 3 :(得分:1)
第一个代码段不会编译,因为变量map
不存在。您调用了参数anyMap
,但尝试将其作为map
访问,修复了该问题,您的代码将从一些rawtypes警告中进行编译
答案 4 :(得分:0)
由于您没有在HashMap
像
HashMap <(Integer,String> hm=new HashMap<(Integer,String>();
如果将类型指定为Integer和String,则不会出现编译时错误。
如果您不知道要在HashMap中添加哪个值,则使用
HashMap<(Object,Object> hm=new HashMap();
答案 5 :(得分:-1)
我遇到了同样的问题。似乎铸造是一个问题。我尝试了下面的代码并且有效。
for(Object entry : hashMap.entrySet())
{
System.out.println(((Entry<Object, Object>) entry).getKey() + " = " + ((Entry<Object, Object>) entry).getValue());
}