Sorry for the yet another "Java generic method is not applicable" question. I would like to know what am I missing in my understanding:
List<E>
is a subtype ofCollection<E>
--> meaning,List<String>
is a subtype ofCollection<String>
Suppose A extends B,
List<A>
is not a subtype ofList<B>
--> but in this case, there's only one typeT
(orString
), so I don't see how the Substitution Principle can explain my problem?
Problem Code:
private <T, K> void genericAddToMapOfLists(HashMap<K, Collection<T>> mapOfLists,
K key, T value) {
if (mapOfLists.containsKey(key)) {
mapOfLists.get(key).add(value);
} else {
List<T> newList = new ArrayList<T>();
newList.add(value);
mapOfLists.put(key, newList);
}
}
private void parseToFruitList(HashMap<String, List<String>> fruit_colors,
String fruitName) {
String color = "";
genericAddToMapOfLists(fruit_colors, fruitName, color);
}
Error:
The method genericAddToMapOfLists(HashMap<K,Collection<T>>, K, T) in the type MyGroceryStore is not applicable for the arguments (HashMap<String,List<String>>, String, String)
The code works when I change the method signature to genericAddToMapOfLists(HashMap<K,List<T>>, K, T)
.
You're right in that "
List<String>
is a subtype ofCollection<String>
". And ifA
extendsB
,List<A>
is not a subtype ofList<B>
.Taking that one step further, a
HashMap<String, List<String>>
is not aHashMap<String, Collection<String>>
.The same reasoning applies, where
A
isList
andB
isCollection
. If aHashMap<String, List<String>>
was aHashMap<String, Collection<String>>
, then you couldput
aVector<String>
into aHashMap<String, List<String>>
by assigning it to aHashMap<String, Collection<String>>
, even though aVector
isn't aList
, and so it's not allowed.