我基于两个类型参数<K,V>
实现了一个地图,其中K
是键类型,V
是值类型。
public class Map<K,V> implements Map<K,V>
{ .. implementation .. }
Map
接口中的一个方法返回一组映射条目。
public Set<java.util.Map.Entry<K,V>> entrySet()
由于我的地图实现基于AVL树,因此另一个类必须实现为Set<MapNode>
public class EntrySet<K,V> implements Set<MapNode<K,V>>
{ .. implementation ..}
为了告诉地图树的节点确实是地图条目,它们的定义如下:
public class MapNode<K,V> implements Map.Entry<K,V>
{ .. implementation .. }
因此,EntrySet包含与Map
本身相同的树,但将树节点视为集合元素(这就是必须单独实现的原因)。
map实现中返回条目集的方法应该如下所示:
/* (non-Javadoc)
* @see java.util.Map#entrySet()
*/
@Override
public Set<java.util.Map.Entry<K,V>> entrySet()
{
return new EntrySet<K,V>(this.comparator,this.tree);
}
然而,编译器给了我以下错误:
&#34;类型不匹配:无法从EntrySet<K,V>
转换为Set<Map.Entry<K,V>>
&#34;
我的问题:
一组Map.Entry<K,V>
必须能够包含所有种Map.Entry<K,V>
,而不仅仅是MapNode<K,V>
个对象。因此,从逻辑上讲,并非EntrySet<K,V>
是Set<Map.Entry<K,V>
的情况,因此这两种集合类型不被视为与分配兼容。
EntrySet<K,V>
,基于相同的树结构(我不希望通过创建或调用另一个数据结构来增加运行时间),这样如果需要Set<Map.Entry<K,V>
,可以返回此类的对象吗?更新
我尝试过以下版本:
public class EntrySet<K,V> implements Set<MapNode<K,V>>
{ .. implementation ..}
在这种情况下,迭代器会产生类似的问题。存在一个整齐地遍历整个树的迭代器类,但它被定义为超类MapNode<K,V>
的迭代器,并且此迭代器不能转换为所需的Iterator<Map.Entry<K,V>>
@Override
public Iterator<Map.Entry<K,V>> iterator()
{
// this iterator type can not be cast to the desired return type
return new TreeNodeIterator<MapNode<K,V>,K>(this.tree);
}
我可能会复制整个迭代器代码并在一个新的独立迭代器类中粗暴地使用它,但我更喜欢更优雅的解决方案。
所以我仍然被困在这里。
更新
与此同时,我创建了另一个独立的迭代器类,用于封装原始迭代器并转换&#34; next&#34;相应的元素。这不是很优雅,但至少它暂时有用。不过,任何更优雅的解决方案都将受到欢迎!
答案 0 :(得分:2)
为什么这些类型不兼容?
问题是Map::entrySet()
的签名表示它应该返回一组任何 Map.Entry<K,V>
个对象。但是,返回的对象仅支持MapNode
个对象的条目。
这是一个问题的(概念性)原因,Set
允许插入和删除元素,而Set<java.util.Map.Entry<K,V>>::add(...)
应能够添加任何内容Map.Entry<K,V>
到集合。但是EntrySet
实施的签名不允许这样做。
如何定义赋值兼容类?
我建议你试试这个:
public class EntrySet<K,V> implements Set<? extends Map.Entry<K,V>>
{ .. implementation ..}
或者
public class EntrySet<K,V> implements Set<Map.Entry<K,V>>
{ .. implementation ..}