Java 如何迭代泛型的hashmap?
我有一个对象模型,它有一个父对象,我在这里称之为MyParent.java。这个类有两个子类,分别名为MySub1.java和MySub2.java 我有两个hashmap,一个包含MySub1实例,另一个包含MySub2实例。我正在尝试编写一段代码,它可以处理两个HashMaps并执行完全相同的操作(稍后,使用MySub1或MySub2实例会产生一些效果,但在这里不会) 以下是编译的代码部分: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
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
的属性。这没什么错。