【问题标题】:Why does this method with wildcards work?为什么这种带有通配符的方法有效?
【发布时间】:2013-11-22 11:22:51
【问题描述】:

我遇到了这个问题:

我们得到了一个地图界面:

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 的子类,它如何工作?这不就像在List&lt;Fruit&gt; 中搜索Apple 一样吗?您将如何遍历该列表?

put 方法也是如此:它如何迭代具有许多不同类型的地图?

这可能与地图的实现有关。

所以也许真正的问题是包含许多 K 和 V 超类型的映射如何知道迭代 K。

调用此方法的示例如下:

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);

这个包含浮点数和整数的映射如何查找浮点类型的键(在 put 和 containsKey 中)?

我希望得到一些解释。

【问题讨论】:

    标签: java generics wildcard bounded-wildcard


    【解决方案1】:

    这被称为The Get and Put Principle:当您只从结构中获取值时使用extends 通配符,当您只将值放入结构时使用super 通配符,并且不要使用获取和放置时的通配符

    这个包含浮点数和整数的映射如何查找一个键 float 类型(在 put 和 containsKey 中)?

    有趣的短语? super K 表示目标Map 可能包含K超类型 的任何类型的元素。这称为下界通配符,它​​将未知类型限制为特定类型或该类型的超类型。

    例如,List&lt;Integer&gt;List&lt;? super Integer&gt; 更具限制性,因为前者仅匹配 Integer 类型的列表,而后者匹配任何类型为 Integer 超类型的列表。


    对于您的上下文的MyMap &lt;Number, Number&gt; m,它的类型为Number,它是IntegerFloat 的超类型。所以它可以包含IntegerFloat 类型的元素。甚至Double 也是。因为它们都是Number 的子类型。超类型实例总是可以引用子类型。

    请查看:

    1. Lower Bounded Wildcards
    2. Guidelines for Wildcard Use

    【讨论】:

    • 所以也许我的问题应该是:Map 实现在包含许多不同的超类型时如何迭代子类型。
    • +1 用于在 Effective Java 中提及 Naftalin 和 Wadler 的 Get and Put Principle Bloch 提供以下助记符:PECS 代表 producer-extends, consumer-super
    • @Shookie,我已经更新了答案。你可能对? super K有错误的想法
    • @alfasin,谢谢。我实际上是在抱怨寻找在线参考,以便 OP 可以轻松阅读描述,但似乎我别无选择,只能提及这本书
    • @Sage - 我知道他们俩的意思。我了解它们在方法中的使用方式,但不了解 Map 将如何工作,因为其中有不止一种类型。我已更新问题以供澄清。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多