【问题标题】:Why doesn’t Map<String, Set<String>> match Map<T, Set<?>>? [duplicate]为什么 Map<String, Set<String>> 不匹配 Map<T, Set<?>>? [复制]
【发布时间】:2016-11-08 14:30:20
【问题描述】:

我有一个带有以下签名的方法:

public <T> int numberOfValues(Map<T, Set<?>> map)

但是我不能通过 Map&lt;String, Set&lt;String&gt;&gt; 调用它。例如,以下内容无法编译:

Map<String, Set<String>> map = new HashMap<>();
numberOfValues(map);

错误信息是:

numberOfValues (java.util.Map<java.lang.String,java.util.Set<?>>) in class cannot be applied to (java.util.Map<java.lang.String,java.util.Set<java.lang.String>>)

但是,如果我更改为以下一切都很好:

public <T, V> int numberOfValues(Map<T, Set<V>> map)

但是我对V 一点也不感兴趣,因为我只想知道每个集合的大小。

为了完整起见,这是整个方法:

public <T, V> int numberOfValues(Map<T, Set<V>> map) {
    int n = 0;
    for (T key : map.keySet()) {
        n += map.get(key).size();
    }
    return n;
}

我知道它也可以像这样完成,但这不是问题的重点:)

public <T> int numberOfValues(Map<?, Set<T>> map) {
    int n = 0;
    for (Set<T> value : map.values()) {
        n += value.size();
    }
    return n;
}

更新:实现相同目标的另一种方法

public <T> int numberOfValues(Map<?, Set<T>> map) {
    int n = 0;
    for (Object key : map.keySet()) {
        n += map.get(key).size();
    }

    return n;
}

最终更新: 感谢 Jorn 的回答,这是最终的实现……

public int numberOfValues(Map<?, ? extends Set<?>> map) {
    int n = 0;
    for (Set<?> value : map.values()) {
        n += value.size();
    }
    return n;
}

【问题讨论】:

标签: java generics wildcard


【解决方案1】:

您错过了Set&lt;?&gt; 也用作通用参数的事实。并且泛型是不变的。即当参数为Map&lt;String, Set&lt;?&gt;&gt; 时,传递的参数必须恰好是Map&lt;String, Set&lt;?&gt;(或子类型)。而Set&lt;V&gt; 则推断类型参数。

您可以使用有界通配符解决此问题:

public <T> int numberOfValues(Map<T, ? extends Set<?>> map) {
    ...
}

【讨论】:

  • 谢谢,这是有道理的。我编辑了问题并添加了一个完全没有类型的实现。
【解决方案2】:

提示:

在你的numberOfValues 方法中,写类似

的东西是完全合法的
Set<Object> set = new HashSet<>();
set.add(1);
set.add("Powned");
map.put(null, set);

您可以将null 替换为映射中已有的合适键以进行有效映射,从而彻底破坏周围代码中的类型安全性。

推断或显式定义集合的类型,或添加通配符绑定以防止变异映射访问(如? extends Set&lt;?&gt;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-26
    • 2021-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-17
    • 2021-04-13
    • 1970-01-01
    相关资源
    最近更新 更多