1

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?

4

2 回答 2

3

这里的问题很微妙,但它基于这样一个事实,即在 Java 泛型中, aType<A>不是 a Type<B>,即使AextendsB也是如此。在这里,AArrayListBList

您定义了 a HashMap<String,ArrayList<Pair<String,Integer>>>,但您的方法需要 a Map<String,List<Pair<String,Integer>>>。尝试k使用List而不是定义ArrayList,它应该可以工作:

HashMap<String,List<Pair<String,Integer>>> k =
    new HashMap<String, List<Pair<String, Integer>>>();

或者定义你的dsp方法来ArrayList代替:

public static <T> int dsp(T start, Map<T, ArrayList<Pair<T, Integer>>> adjList, T goal) {

此外,即使允许,您也应该访问静态方法,例如dsp通过类的实例。为清楚起见,最好使用类名访问它:

// GraphSearch.dsp instead of g.dsp.
System.out.println("dsp from A to E is" + GraphSearch.dsp("a", k, "e"));
于 2013-10-26T00:41:24.877 回答
3

因为Map<T, ArrayList<...>>不是子类型Map<T, List<...>>。请参阅此线程(以及其他线程)了解原因。

Map<T, ? extends List<Pair<T, Integer>>>如果您想支持该用例,您的通用应该是。

另一种选择是更改k为类型Map<String,List<Pair<String,Integer>>>- 即使您确实使用? extends语法,这也是可取的,因为它可以让您对接口进行编程并更好地使用多态性。例如,k如果您以后决定值应该是LinkedLists 而不是ArrayLists,则不必更改。

于 2013-10-26T00:41:43.910 回答