有人可以解释,为什么下一个代码没有编译? 我正在为它创建一个部分专用的Map和Map.Entry:
public class Trie<T> implements Map<String, T> {
private class TrieEntry<S> implements Map.Entry<String, S> {
// stupid implementation here
}
// uninterested code here
}
这里一切正常,但后来我正在实现entrySet()方法:
public Set<java.util.Map.Entry<String, T>> entrySet() {
Set<java.util.Map.Entry<String, T>> x = new HashSet<TrieEntry<T>>();
// some uninterested code here
}
Eclipse说
“类型不匹配:无法从HashSet<Trie<T>.TrieEntry<T>>
转换为Set<Map.Entry<String,T>>
”
因此,在我看来TrieEntry<T>
应该展开到Map.Entry<String, T>
,并且它符合定义中的表达。
我哪里错了?
答案 0 :(得分:5)
TrieEntry<T>
是Map.Entry<String, T>
,你是对的。 HashSet<TrieEntry<T>>
也是Set<TrieEntry<T>>
,但 <{1}}。
如果是,你可以这样做:
Set<Map.Entry<String, T>>
所以现在trieSet现在包含Set<TrieEntry<T>> trieSet = ...;
Set<Map.Entry<String, T>> mapSet = trieSet;
mapSet.add(mapEntry);
!这会打破泛型。
那么如何解决这个特殊问题呢?轻松 - 使用有界通配符:
Map.Entry<String, T>
您可以将Set<? extends Map.Entry<String, T>> x = new HashSet<TrieEntry<T>>();
视为“至少? extends Map.Entry<String, T>
”的任何内容。
好的,现在来看你的实施问题。我实际上相信,由于方法entrySet()的当前定义,这是无法解决。 应返回Map.Entry<String, T>
,但 返回? extends Map.Entry<String, T>
。
对于这个问题,实际上有一个bug report(或功能请求)。查看提交日期和优先级,很快就无法实现修复。
所以你有两个选择:
放弃Map.Entry<String, T>
课程并尝试使用TrieEntry
代替,将信息存储在您的密钥和/或值中。
放弃Map.Entry
界面,让自定义Map
方法返回entrySet
。
这两种解决方案可能都不理想,而且可能有更好的解决方案,但这就是我目前可以告诉你的所有内容。
答案 1 :(得分:4)
HashSet
课程实施Set
,但HashSet<some subclass of X>
不是Set<X>
的子类型。你可以这样做:
Set<? extends Map.Entry<String, T>> x = new HashSet<TrieEntry<T>>();
但我怀疑你以后会在entrySet
方法中遇到麻烦(你无法从方法中返回它,因为它仍然要求你返回Set<Map.Entry<String, T>>
)。
另一种解决方案是:
Set<Map.Entry<String, T>> x = new HashSet<Map.Entry<String, T>>();
您可以将TrieEntry<T>
个对象添加到此Set
,并将其从entrySet()
返回。
我认为您还可以通过省略类型参数TrieEntry
来简化S
内部类,并使用封闭类中的T
:
class Trie<T> implements Map<String, T> {
private class TrieEntry extends Map.Entry<String, T> {
// ...
@Override
public T getValue() {
// ...
}
}
// ...
}