大家好,我尝试扩展 HashMap<String,String>
执行“全小写”规则
public class HttpQueryMap extends HashMap<String,String>
{
...
@Override
public void putAll(Map<? extends String, ? extends String> m)
{
...
Iterator<Map.Entry<String,String>> iterator = m.entrySet().iterator();
...
}
...
}
编译时出错
incompatible types
required: Iterator<Entry<String,String>>
found: Iterator<Entry<CAP#1,CAP#2>>
where CAP#1,CAP#2 are fresh type-variables:
CAP#1 extends String from capture of ? extends String
CAP#2 extends String from capture of ? extends String
下一个解决方法可以完成这项工作,但它真的很难看:
public class HttpQueryMap extends HashMap<String,String>
{
...
@Override
public void putAll(Map<? extends String, ? extends String> m)
{
...
Map<String,String> m_str=new HashMap<String,String>();
m_str.putAll(m);
Iterator<Map.Entry<String,String>> iterator = m_str.entrySet().iterator();
...
}
...
}
据我了解,问题是类型变量 String
用于 Iterator<Map.Entry<String,String>>
不扩展 String
(本身)用于 Map<? extends String, ? extends String> m
的声明中
最佳答案
没有迭代器
最简单的方法是使用for-each 循环。即使在这种情况下,您也需要使用与给定 map 中相同的通配符对条目进行参数化。原因是 Entry<? extends String, ? extends String>
不是 Entry<String, String>
的子类型.事实String
是 final
类在这里无关紧要,因为编译器对此一无所知。
for (Entry<? extends String, ? extends String> entry : m.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
}
使用迭代器
如果你真的需要一个迭代器,编译的语法有点令人费解:
Iterator<? extends Entry<? extends String, ? extends String>> iterator =
m.entrySet().iterator();
while (iterator.hasNext()) {
Entry<? extends String, ? extends String> entry = iterator.next();
String key = entry.getKey();
String value = entry.getValue();
}
我原本期望迭代器只是类型 Iterator<Entry<? extends String, ? extends String>>
, 乍一看似乎是 iterator()
的返回类型在 Set<Entry<? extends String, ? extends String>>
上调用的方法这又似乎是 entrySet()
的返回类型调用Map<? extends String, ? extends String>
.
然而,它比这复杂一点。我在这里找到了一个可能的答案:
有趣的部分是:
The problem is that the
entrySet()
method is returning aSet<Map.Entry<capture-of ? extends K, capture-of ? extends V>>
, which is incompatible with the typeSet<Map.Entry<? extends K, ? extends V>>
. It's easier to describe why if I drop theextends K
andextends V
part. So we haveSet<Map.Entry<?, ?>
andSet<Map.Entry<capture-of ?, capture-of ?>>
.The first one,
Set<Map.Entry<?, ?>>
is a set of Map.Entries of different types - ie it is a heterogeneous collection. It could contain aMap.Entry<Long, Date>
and aMap.Entry<String, ResultSet>>
and any other pair of types, all in the same set.On the other hand,
Set<Map.Entry<capture-of ?, capture-of ?>>
is a homogenous collection of the same (albeit unknown) pair of types. Eg it might be aSet<Map.Entry<Long, Date>>
, so all of the entries in the set MUST beMap.Entry<Long, Date>
.
关于java - 具有上限的通配符类型变量的迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16753587/