嵌套逆变类型中的类型不匹配
Type mismatch in nested contravariant type
鉴于这样class(部分)
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。
泛型是不变的。如果您声明一个参数 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) {
...
}
鉴于这样class(部分)
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。
泛型是不变的。如果您声明一个参数 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) {
...
}