Java迭代器返回的结果的不兼容泛型类型

时间:2016-02-10 02:35:59

标签: java generics iterator incompatibility

我有一个对象是一种Map,我试图用迭代器迭代它。但是,我无法通过编译,代码如下。

// Returned from other method, and the run time type is Map<String, B>
Map<String, ? extends A> map = ...

// Option 1: cannot pass.
Iterator<Map.Entry<String, ? extends A>> iterator = map.entrySet().iterator();

// Option 2: cannot pass either.
// Where B is a subclass extends from A
Iterator<Map.Entry<String, B>> iterator = map.entrySet().iterator();

有人可以帮帮我吗?感谢。

3 个答案:

答案 0 :(得分:1)

我建议您使用foreach循环而不是直接使用Iterator

Map<String, ? extends A> map = new HashMap<>();
for (Map.Entry<String, ? extends A> entry : map.entrySet()) {
    String key = entry.getKey();
    A value = entry.getValue();
}

答案 1 :(得分:1)

如果您真的想将Iterator存储在变量中,而不是

// ERROR
Iterator<Map.Entry<String, ? extends A>> iterator = map.entrySet().iterator();

你必须这样做:

Iterator<? extends Map.Entry<String, ? extends A>> iterator = map.entrySet().iterator();

额外? extends的原因是嵌套在Map.Entry<String, ? extends A>声明中的通配符。如果你有一个类型

的变量
Iterator<Map.Entry<String, ? extends A>>

然后原则上每个条目可以具有A的不同子类型的值,因此每个Map.Entry将具有不同的类型。相比之下,

Iterator<? extends Map.Entry<String, ? extends A>>

表示每个条目都是单一类型。 (但你不知道它是什么类型,因为它是一个通配符。)

实际上,这与Iterator无关,因为您只从中获取Map.Entry<String, ? extends A>类型的对象。但是如果你有其他类型允许你把东西放进去(比如Set),那么差异就会很大。例如,

Set<? extends Map.Entry<String, ? extends A>>

只允许从集合中获取条目,但

Set<Map.Entry<String, ? extends A>>

允许向集合中添加条目,这些条目可能包含不同的A类型,可能会污染集合。

有关此问题的进一步讨论,请参阅

以及这些Stack Overflow问题:

答案 2 :(得分:0)

我这应该做的伎俩

for (Map.Entry<String, ? extends A> entry : map.entrySet())
{
   String key = entry.getKey();
    A value = entry.getValue();
}