简体   繁体   English

设置不适用于Java通用方法中的Collection

[英]Set not applicable for Collection in generic method with Java

I defined a generic function in java with the signature 我用签名在Java中定义了一个泛型函数

<V> List<V> sortedValuesFromMap(Map<?, Collection<V>> keysValues, Comparator<V> comp)

which takes a Map mapping any type of keys to a Collection of some defined type V, and a comparator of type V. The method works great and the Java compiler does not complain about type incompatibility. 它使用Map将任何类型的键映射到一些已定义的V类型的Collection以及V类型的比较器。该方法很好用,并且Java编译器不会抱怨类型不兼容。

But now when I want to apply this method to a map of the type Map<String, Set<String>> and the AlphanumComparator (see here ) the compiler says : 但是现在,当我想将此方法应用于Map<String, Set<String>>AlphanumComparator类型的Map<String, Set<String>> (请参见此处 )时,编译器会说:

The method sortedValuesFromMap(Map<?,Collection<V>>, Comparator<V>) in the type MyUtils is not applicable for the arguments ( Map<String,Set<String>, AlphanumComparator ) sortedValuesFromMap(Map<?,Collection<V>>, Comparator<V>)不适用于参数( Map<String,Set<String>, AlphanumComparator

Turning Collection to Set in the signature of sortedValuesFromMap would fix it – but I do not want to do that. sortedValuesFromMap的签名中的Collection SetSet可以解决该问题-但我不想这样做。 So why is Java forcing me to do so, although Set<E> is implementing Collection<E> ? 那么,尽管Set<E> 实现了 Collection<E> ,但是为什么Java强制我这样做呢?

PS: If someone is interested in my code: PS:如果有人对我的代码感兴趣:

public static <V> List<V> sortedValuesFromMap(Map<?, Collection<V>> keysValues,
        Comparator<V> comp) {
    List<V> values = new LinkedList<V>();
    for (Collection<V> col : keysValues.values()) {
        values.addAll(col);
    }
    Collections.sort(values, comp);
    return values;
}

Just as a List<Dog> is not a List<Animal> , a Map<String, Set<String>> is not a Map<String, Collection<String>> and it's not a Map<?, Collection<String>> . 就像List<Dog>不是List<Animal>Map<String, Set<String>>不是Map<String, Collection<String>>并且它不是Map<?, Collection<String>>

The solution here is to add a wildcard in place of Set to allow a subclass in the generic type parameter. 这里的解决方案是添加一个通配符代替Set以允许泛型类型参数中的子类。

//                                                   Add v
public static <V> List<V> sortedValuesFromMap(Map<?, ? extends Collection<V>> keysValues,
    Comparator<V> comp) {

Your problem is that Map<String,Set<V>> is not a subtype of Map<String,Collection<V>> . 您的问题是Map<String,Set<V>>不是Map<String,Collection<V>>的子类型。 Think about what type x can be, if it's legal to write x.put("Hello",new ArrayList<V>()); 考虑一下x可以是什么类型,如果写x.put("Hello",new ArrayList<V>());是合法的x.put("Hello",new ArrayList<V>());

In this case, x could be a Map<String,Collection<V>> , since an ArrayList<V> is certainly a Collection<V> . 在这种情况下, x可以是Map<String,Collection<V>> ,因为ArrayList<V>当然是Collection<V> But it couldn't be a Map<String,Set<V>> , since an ArrayList<V> is not a Set<V> . 但这不能是Map<String,Set<V>> ,因为ArrayList<V>不是Set<V> Therefore it's untrue to say that any Map<String,Set<V>> "is a" Map<String,Collection<V>> . 因此,不能说任何Map<String,Set<V>>是一个Map<String,Collection<V>>

The type that you want is either Map<String,? extends Collection<V>> 您想要的类型是Map<String,? extends Collection<V>> Map<String,? extends Collection<V>> or Map<?,? extends Collection<V>> Map<String,? extends Collection<V>>Map<?,? extends Collection<V>> Map<?,? extends Collection<V>> . Map<?,? extends Collection<V>> Both Map<String,Set<V>> and Map<String,Collection<V>> are subtypes of these types. Map<String,Set<V>>Map<String,Collection<V>>都是这些类型的子类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM