java – 具有上限的通配符类型变量的迭代器

前端之家收集整理的这篇文章主要介绍了java – 具有上限的通配符类型变量的迭代器前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
大家好,我尝试扩展HashMap< String,String>强制执行“全小写”规则
  1. public class HttpQueryMap extends HashMap<String,String>
  2. {
  3. ...
  4. @Override
  5. public void putAll(Map<? extends String,? extends String> m)
  6. {
  7. ...
  8. Iterator<Map.Entry<String,String>> iterator = m.entrySet().iterator();
  9. ...
  10. }
  11. ...
  12. }

我收到编译时错误

  1. incompatible types
  2. required: Iterator<Entry<String,String>>
  3. found: Iterator<Entry<CAP#1,CAP#2>>
  4. where CAP#1,CAP#2 are fresh type-variables:
  5. CAP#1 extends String from capture of ? extends String
  6. CAP#2 extends String from capture of ? extends String

下一个解决方案可以完成这项工作,但实际上很丑陋:

  1. public class HttpQueryMap extends HashMap<String,? extends String> m)
  2. {
  3. ...
  4. Map<String,String> m_str=new HashMap<String,String>();
  5. m_str.putAll(m);
  6. Iterator<Map.Entry<String,String>> iterator = m_str.entrySet().iterator();
  7. ...
  8. }
  9. ...
  10. }

据我所知,问题是Iterator中使用的类型变量String< Map.Entry< String,String>>不扩展Map<?声明中使用的String(本身)扩展字符串,? extends String>米

解决方法

没有迭代器

最简单的方法是使用for-each循环.即使在这种情况下,您也需要使用与给定映射中相同的通配符对Entry进行参数化.原因是Entry<?扩展字符串,? extends String>不是Entry< String,String>的子类型. String是最终类的事实在这里是无关紧要的,因为编译器不知道这一点.

  1. for (Entry<? extends String,? extends String> entry : m.entrySet()) {
  2. String key = entry.getKey();
  3. String value = entry.getValue();
  4. }

有了Iterator

如果你真的需要一个Iterator,那么编译的语法有点莫名其妙:

  1. Iterator<? extends Entry<? extends String,? extends String>> iterator =
  2. m.entrySet().iterator();
  3.  
  4. while (iterator.hasNext()) {
  5. Entry<? extends String,? extends String> entry = iterator.next();
  6. String key = entry.getKey();
  7. String value = entry.getValue();
  8. }

我最初期望迭代器只是Iterator类型< Entry<?扩展字符串,? extends String>>,它最初看起来是在Set< Entry<?上调用的iterator()方法的返回类型.扩展字符串,? extends String>>这反过来似乎是在Map<?上调用的entrySet()的返回类型扩展字符串,? extends String>.

但是,它比这复杂一点.我在这里找到了一个可能的答案:

http://mail-archives.apache.org/mod_mbox/harmony-dev/200605.mbox/%3Cbb4674270605110156r4727e563of9ce24cdcb41a0c8@mail.gmail.com%3E

有趣的是这个:

The problem is that the entrySet() method is returning a
Set<Map.Entry<capture-of ? extends K,capture-of ? extends V>>,
which is incompatible with the type Set<Map.Entry<? extends K,? extends V>>.
It’s easier to describe why if I drop the extends K and extends V part.
So we have Set<Map.Entry<?,?> and Set<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 a
Map.Entry<Long,Date> and a Map.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 a
Set<Map.Entry<Long,Date>>,so all of the entries in the set MUST be
Map.Entry<Long,Date>.

猜你在找的Java相关文章