Reputation: 118
I want to write a method that can accept the parameter:
Map<String, [the type here could be anything]>
So, here is what I coded:
/**
* Get list value from a map, empty list if there's no key matched
*/
private List<? extends Object> getListValueFromMap(Map<String, List<? extends Object>> map, String key) {
List<? extends Object> list = map.get(key);
return list == null ? EMPTY_LIST : list;
}
And the EMPTY_LIST
is defined as below:
List<Object> EMPTY_LIST = Collections.unmodifiableList(new ArrayList<Object>());
The problem is that when I call this method with following code, Eclipse tells me a error that the given parameter's type is not applicable.
getListValueFromMap(cityNameMap, "key");
And the error is:
The method getListValueFromMap(Map<String,List<? extends Object>>, String) in the type ChinaAreaResource is not applicable for the arguments (Map<String,List<City>>, String)
Where am I going wrong with this?
Here is the definition of cityNameMap
:
/** map city's name to city list */
private Map<String, List<City>> cityNameMap;
Upvotes: 3
Views: 145
Reputation: 106508
It's important to take note of what ? extends Object
actually represents in generics.
In its current incantation, it is an upper-bounded wildcard which has its upper bound as Object
. Ideally, this would imply that you could use any list from it, but since generics are invariant, that wouldn't be the case here at all - you could only use lists which have the same bound.
Since the containing type of the list may change from map to map, set your bound on a generic type to get at the list you care about instead.
private <T> List<? extends T> getListValueFromMap(Map<String, List<T>> map, String key) {
List<? extends T> list = map.get(key);
return list == null ? EMPTY_LIST : list;
}
Be sure to update your EMPTY_LIST
dependency accordingly; obviously in this state, you can't return the list bounded with Object
.
This has the advantage of allowing you to pass your list in with any supplied type, and you won't be able to simply add elements to it once you retrieve them from your map due to the way the generic argument is done on the list.
Upvotes: 4
Reputation: 5813
You could do this:
private <T> List<T> getListValueFromMap(Map<String, List<T>> map, String key) {
//
}
Both don't give me any issues in my IDE (IntelliJ 2016.1.1), but it could be that yours has different settings.
Upvotes: 0