我遇到了这个问题:
我们获得了一个地图界面:
interface MyMap<K,V>{
public void put (K key, V value);
public V get (K key);
public boolean containsKey (K key);
}
我们希望实现一个方法addToMyMap
,其签名是(我们需要填写缺失的部分(点):
void addToMyMap(MYMap<....> m, List<....> keys, .... newValue)
该方法将扫描键列表,如果地图中不存在每个键,它将添加newValue作为值。
作为答案给出的实现如下:
public static <K,V> void addToMyMap (MyMap <? super K, ? super V> m, List<? extends K> keys, V newValue)
{
for (K key: keys)
{
if (!m.containsKey(key))
{
m.put(key,newValue);
}
}
}
我不完全确定为什么这个实现是正确的。如果containsKey
方法获得K的子类,它如何工作?是不是在Apple
中搜索List<Fruit>
?你怎么会迭代那个名单?
同样适用于put
方法:如何迭代具有多种不同类型的地图?
这可能与地图的实施有关。
所以也许真正的问题是,包含许多超类型K和V的地图如何知道迭代Ks。
调用此方法的示例如下:
MyMap <Number, Number> m = new MyMapImpl<Number,Number>();
m.put(new Integer (1) , new Float(7.2));
m.put (new Float(3.1), new Double(9.99));
List<Integer> lst = new List<Integer>();
lst.add(1); lst.add(2); lst.add(3);
Float f = new Float (55.5);
Util.addToMyMap (m,lst,f);
这个映射如何保存float和整数查找一个float类型的键(在put和containsKey中)?
我很感激一些解释。
答案 0 :(得分:4)
这称为The Get and Put Principle
:当您只从结构中获取值时使用extends
通配符,当您只将值放入结构时使用super
通配符,并且<当你得到并放置时,不要使用通配符。
这个映射如何保存浮点数和整数查找键 float类型(在put和containsKey中)?
古怪的短语? super K
表示目标Map
可能包含{{1>}的超类型的任何类型的元素。这称为下限有界通配符,它将未知类型限制为特定类型或该类型的超类型。
例如,K
比List<Integer>
更具限制性,因为前者仅匹配Integer类型的列表,而后者匹配任何类型的列表{@ 1}}的超类型。
对于您的上下文List<? super Integer>
,其类型为Integer
,它是MyMap <Number, Number> m
和Number
的超类型。因此,它可以包含Integer
和Float
类型的元素。甚至Integer
也是如此。因为它们都是Float
的子类型。超类型实例始终可以引用子类型。
请查看: