Вызов универсального метода в классе, не относящемся к общим требованиям, в основном

У меня есть класс GraphSearch, который определяется как таковой:

public class GraphSearch{
///code
}

В этом классе используется метод с параметрическими параметрами:

public static <t> int dsp(T start, Map<t, list<pair<t,="" integer="">>> adjList, T goal) {
///code}
</t,></t>

У меня есть основное, что я делаю эту настройку и вызываю метод как таковой:

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
</string,></string,arraylist<pair<string,integer>

Тогда в основном

System.out.println("dsp from A to E is" + g.dsp("a", k, "e"));

Я получаю сообщение об ошибке.

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)
</string,arraylist<pair<string,integer></t,list<pair<t,integer>

А почему бы не? Является ли ArrayList не списком? Является ли строка не общеприемлемым типом? Является ли Хашмап не картой?

Что происходит?

2 ответа

Проблема здесь тонкая, но она основана на том, что в Java generics Type не является Type, даже если A расширяет B Здесь A - ArrayList, а B - List.

Вы определили HashMap<string,arraylist<pair<string,integer>>></string,arraylist<pair<string,integer>, но ваш метод ожидает Map<string,list<pair<string,integer>>></string,list<pair<string,integer>. Попробуйте определить k со List вместо ArrayList, и он должен работать:

HashMap<string,list<pair<string,integer>>> k =
 new HashMap<string, list<pair<string,="" integer="">>>();
</string,></string,list<pair<string,integer>

ИЛИ определите свой метод dsp для работы с ArrayList:

public static <t> int dsp(T start, Map<t, arraylist<pair<t,="" integer="">>> adjList, T goal) {
</t,></t>

Кроме того, даже если это разрешено, вы должны получить доступ к статическим методам, таким как dsp через экземпляр класса. Он предпочел получить доступ к нему с именем класса, для ясности:

// GraphSearch.dsp instead of g.dsp.
System.out.println("dsp from A to E is" + GraphSearch.dsp("a", k, "e"));


Поскольку Map<t, arraylist<...="">></t,> не является подтипом Map<t, list<...="">></t,>. Смотрите эту тему (среди прочего) для чего.

Ваша общая информация должна быть Map<t,? extends="" list<pair<t,="" integer="">>></t,?> Map<t,? extends="" list<pair<t,="" integer="">>></t,?> если вы хотите поддержать этот прецедент.

Другой альтернативой было бы изменить k на тип Map<string,list<pair<string,integer>>></string,list<pair<string,integer> - это предпочтительнее, даже если вы используете ? extends ? extends синтаксис, поскольку он позволяет вам программировать интерфейсы и лучше использовать полиморфизм. Например, вам не придется менять k если позже вы решите, что значения должны быть LinkedList вместо ArrayList.

licensed under cc by-sa 3.0 with attribution.