Java 如何迭代泛型的hashmap?

Java 如何迭代泛型的hashmap?,java,generics,iterator,hashmap,covariance,Java,Generics,Iterator,Hashmap,Covariance,我有一个对象模型,它有一个父对象,我在这里称之为MyParent.java。这个类有两个子类,分别名为MySub1.java和MySub2.java 我有两个hashmap,一个包含MySub1实例,另一个包含MySub2实例。我正在尝试编写一段代码,它可以处理两个HashMaps并执行完全相同的操作(稍后,使用MySub1或MySub2实例会产生一些效果,但在这里不会) 以下是编译的代码部分: HashMap<String, ? extends MyParent> map = nu

我有一个对象模型,它有一个父对象,我在这里称之为MyParent.java。这个类有两个子类,分别名为MySub1.java和MySub2.java

我有两个hashmap,一个包含MySub1实例,另一个包含MySub2实例。我正在尝试编写一段代码,它可以处理两个HashMaps并执行完全相同的操作(稍后,使用MySub1或MySub2实例会产生一些效果,但在这里不会)

以下是编译的代码部分:

HashMap<String, ? extends MyParent> map = null;
if (some condition)
    map = // get a HashMap<String, MySub1>
if (some other condition)
    map = // get a HashMap<String, MySub2>
if(map != null && map.size() > 0){
    Iterator<Entry<String, ? extends MyParent>> i = map.entrySet().iterator();
    while(i.hasNext()){
        Map.Entry<String, MyParent> pair = (Map.Entry<String, MyParent>) i.next();
        // get the object from the pair and handle it
    }
}
Eclipse会在创建迭代器的行上打印此错误消息:

 cannot convert from Iterator<Map.Entry<String,capture#5-of ? extends MyParent>> to Iterator<Map.Entry<String,? extends MyParent>>
无法从迭代器转换为迭代器
我真的没有收到错误信息。如果我更改代码的第一行:

HashMap<String, MyParent> map = null
HashMap-map=null
现在,不工作的代码可以工作了,但工作代码不再工作,出现以下错误消息:

cannot convert from HashMap<String,MySub1> to HashMap<String,MyParent>
无法从HashMap转换为HashMap

有什么想法吗?

您可以将String和MyParent的一对实例放入
映射中。不能将该对放入
映射中。因此,从后一个映射到前一个映射的转换是不可能的(正如您上次的错误消息所述)。另见

相同问题的一个版本适用于迭代器。如果实际映射是
映射
,它将返回一个
迭代器
,该迭代器不能转换为
迭代器
,即使
映射项
映射项
。例如,将编译以下内容:

Map.Entry someEntry=Map.entrySet().iterator().next()

另一个通配符(
)有助于:

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

Iterator我不知道您的确切要求,但是在同一个映射中有多个对象类型可能会产生严重的维护问题。希望您考虑过以下情况

  • 当这两个条件在以后某个时间点都满足时

  • 当Mysub1/Mysub2的行为改变时

  • 当其他人正在维护代码时

    我仍然建议使用单独的实例。为了避免到处携带多个贴图,您可能希望将它们环绕在一个对象中


  • 您的代码没有编译(没有测试运行时)。但是你的修改不是我所期望的,我真的不明白。。。你能解释一下为什么
    ?扩展地图。是否需要输入
    ?我想你的部分解释在提交时被网站破坏了。你文章中的两个
    迭代器>
    肯定是一段没有用反引号正确转义的代码。@Wis这也是我发现很难理解的。A
    ?扩展作业左侧的内容
    ,无需引用与
    完全相同的类型?扩展右侧的内容
    。如果您发现上面的代码很难看,请尝试将“未编译的代码”移动到一个方法
    public void removeSome(Map-Map)
    ,并在其中使用
    迭代器。@Wis谢谢。修复了,希望如此。thx对于答案来说,泛型并不那么明显。总体概念不错,但细节有点棘手。顺便说一下,我的一位同事告诉我,泛型是一种在不需要时添加类型安全性的方法。他告诉我,他总是使用
    迭代器i=map.entrySet().Iterator()
    ,而不进行任何类型声明,并添加了
    @SuppressWarning
    注释,以消除编译器对取消选中类型转换的警告。这两个条件在运行时似乎都能很好地工作。这两个条件是相互排斥的,之前的一个测试已经验证了这两个条件中的一个是正确的,而不是两者都是正确的。实际上,我的类是没有任何逻辑的DTO。只是一个将数据映射到数据库的容器。你的第三个音符,嗯。。。任何维护别人代码的人都会发现它很丑陋;)同一地图中没有多个对象类型。他有一个只包含
    MySub1
    值或
    MySub2
    值的映射,并且希望在不知道子类属性的特定知识的基础上,以相同的方法处理这两个值,只知道来自
    MyParent
    的属性。这没什么错。