Reputation: 6592
I have a class, GraphSearch, defined as such:
public class GraphSearch{
///code
}
In this class is the generics-parameterized method:
public static <T> int dsp(T start, Map<T, List<Pair<T, Integer>>> adjList, T goal) {
///code}
I have a main I do this setup and call the method as such:
GraphSearch g = new GraphSearch();
HashMap<String,ArrayList<Pair<String,Integer>>> k = new HashMap<String, ArrayList<Pair<String, Integer>>>();
////various setup to fill my map with valid stuff
///Pair is a class I made in my package
Then in main is
System.out.println("dsp from A to E is" + g.dsp("a", k, "e"));
I get an error.
The method dsp(T, Map<T,List<Pair<T,Integer>>>, T) in the type GraphSearch is not applicable for the arguments (String, HashMap<String,ArrayList<Pair<String,Integer>>>, String)
Well, why not? Is an ArrayList not a List? Is a String not a Generic-acceptable type? Is a Hashmap not a Map?
What's going on?
Upvotes: 1
Views: 105
Reputation: 43391
Because Map<T, ArrayList<...>>
is not a subtype of Map<T, List<...>>
. See this thread (among others) for why.
Your generic should be Map<T, ? extends List<Pair<T, Integer>>>
if you want to support that use case.
Another alternative would be to change k
to be of type Map<String,List<Pair<String,Integer>>>
-- this is preferable even if you do use the ? extends
syntax, as it lets you program to the interfaces and use polymorphism better. For instance, you won't have to change k
if you later decide that the values should be LinkedList
s instead of ArrayList
s.
Upvotes: 3
Reputation: 178263
The problem here is subtle, but it's based in the fact that in Java generics, a Type<A>
is not a Type<B>
, even if A
extends B
. Here, A
is ArrayList
, and B
is List
.
You defined a HashMap<String,ArrayList<Pair<String,Integer>>>
, but your method expects a Map<String,List<Pair<String,Integer>>>
. Try defining k
with List
instead of ArrayList
, and it should work:
HashMap<String,List<Pair<String,Integer>>> k =
new HashMap<String, List<Pair<String, Integer>>>();
OR define your dsp
method to work with ArrayList
instead:
public static <T> int dsp(T start, Map<T, ArrayList<Pair<T, Integer>>> adjList, T goal) {
Additionally, even if it's allowed, you should access static methods such as dsp
via an instance of the class. It's preferred to access it with the class name, for clarity:
// GraphSearch.dsp instead of g.dsp.
System.out.println("dsp from A to E is" + GraphSearch.dsp("a", k, "e"));
Upvotes: 3