鉴于此类(部分内容)
import java.util.*;
import java.util.stream.Collectors;
public class A {
private Map<String, Set<String>> map = new LinkedHashMap<>();
public Map<String, Collection<String>> getMap() {
return Collections.unmodifiableMap(map);
}
public static <K, V> Map<K, V> sorted(Map<K, V> map, Comparator<Map.Entry<? super K, ? super V>> comparator) {
return map
.entrySet()
.stream()
.sorted(comparator)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
public Map<String, Collection<String>> getSortedMap() {
Comparator<Map.Entry<String, Collection<String>>> cmp =
Map.Entry.comparingByValue(Comparator.comparingInt(Collection::size));
return sorted(getMap(), cmp);
}
}
我在编译时遇到错误
error: method sorted in class A cannot be applied to given types;
return sorted(getMap(), cmp);
^
required: Map<K,V>,Comparator<Entry<? super K,? super V>>
found: Map<String,Collection<String>>,Comparator<Entry<String,Collection<String>>>
reason: cannot infer type-variable(s) K,V
(argument mismatch; Comparator<Entry<String,Collection<String>>> cannot be converted to Comparator<Entry<? super K,? super V>>)
where K,V are type-variables:
K extends Object declared in method <K,V>sorted(Map<K,V>,Comparator<Entry<? super K,? super V>>)
V extends Object declared in method <K,V>sorted(Map<K,V>,Comparator<Entry<? super K,? super V>>)
1 error
当我将A.sorted
签名更改为comparator
参数(即<K, V> Map<K, V> sorted(Map<K, V> map, Comparator<Map.Entry<K, V>> comparator)
}不变时,它会毫无问题地进行编译。但是,我不认为我的代码违反了任何打字关系。这是Java类型推断的问题吗?
我正在使用OpenJDK 8。
答案 0 :(得分:2)
泛型是不变的。如果您声明参数Comparater<T>
,那么它完全符合Comparator<T>
。在这种情况下,您可以通过地图K
和V
生成K = String
和V = Collection<String>
。这将产生第二个参数Comparator<Entry<? super String, ? super Collection<String>>>
,并且您不能为此分配Comparator<Entry<String,Collection<String>>>
,因为比较器的类型参数不会完全匹配。
您可以改为声明Comparator
反变量:
public static <K, V> Map<K, V> sorted(Map<K, V> map,
Comparator<? super Map.Entry<K, V>> comparator) {
...
}