-->

迭代一个的entrySet地图(Iterating over a map entryset)

2019-07-20 02:08发布

我需要遍历条目集地图从中我不知道它的参数类型。

当对这种迭代的entrySet,为什么这个不能编译?

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()) {
        ...
    }
}

Answer 1:

你在你第一次得到的错误是:

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>

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()



Answer 2:

这是因为你使用原始类型地图,因此map.entrySet()让你一个非参数化设置哪些回报率对象上迭代,不进入。

<?,>一个简单的,而优雅的解决方案是使用地图,这将仍然允许你通过任何地图,但在另一方面势力map.entrySet()到已设置的返回值<输入>:

public void test(Map<?,?> map) {        
    for(Entry e : map.entrySet()){
        Object key = e.getKey();
        Object value = e.getValue();
    }       
}


Answer 3:

在第一个例子中,map.entrySet()返回设置,当你在循环遍历您使用迭代器。 没有关于设置内容类型的信息,所以Java使用对象为对象的基本类型和编译器会告诉你,它不能转换对象条目。

Set<Map.Entry<K, V>> entrySet();

当您使用原始地图类型,返回的entrySet刚刚成立,没有任何类型的信息。

在第二个例子中,你manualy转换设置设置<输入>(带警告)。 现在的Java里面知道。 所以,你可以迭代。

在最后一个例子,你知道的地图类型,所以返回的entrySet正确输入设置,您可以不需要任何类型的约定进行迭代。



Answer 4:

第一代码片段不会编译,因为变量map不存在。 你叫参数anyMap但试图访问它map ,解决这个问题,你的代码将一些rawtypes警告放在一边编译



Answer 5:

你得到的编译时间rrror,因为你没有在指定类型HashMap

喜欢

HashMap <(Integer,String> hm=new HashMap<(Integer,String>();  

如果指定类型的整数和字符串,你没有得到编译时错误。

如果你不知道它的价值是要添加在你的HashMap然后使用

HashMap<(Object,Object> hm=new HashMap();  


Answer 6:

我所面临的同样的问题。 看来,铸造是一个问题。 我想下面的代码和它的工作。

    for(Object entry : hashMap.entrySet())
    {
        System.out.println(((Entry<Object, Object>) entry).getKey() + " = " + ((Entry<Object, Object>) entry).getValue());

    }


文章来源: Iterating over a map entryset