Ответ 1
List<?>
означает "Список чего угодно", поэтому два объекта с этим типом не совпадают: может быть список String
, а другой - <<22 > . Очевидно, что это не то же самое.
List<T>
означает "Список чего-либо, но если вы снова видите T
, то тот же T
".
Вы должны сообщить компилятору, когда имеете в виду один и тот же тип в разных местах. Попробуйте:
public static <T extends Comparable<? super T>> List<T> merge(Set<List<T>> lists) {
List<T> result = new LinkedList<T>();
HashBiMap<List<T>, Integer> location = HashBiMap.create();
[EDIT]. Что означает <T extends Comparable<? super T>> List<T>
? Первая часть определяет тип T
со следующими свойствами: он должен реализовать интерфейс Comparable<? super T>
(или Comparable<X>
, где X
также определяется в терминах T
).
? super T
означает, что тип, поддерживаемый Comparable
, должен быть T
или один из его супер типов.
Представьте себе на мгновение это наследование: Double extends Integer extends Number
. Это неверно на Java, но представьте, что Double
- это всего лишь Integer
плюс доля. В этом случае a Comparable
, который работает для Number
, также работает для Integer
и Double
, так как оба получаются из Number
. Таким образом, Comparable<Number>
удовлетворяет части super
для T
, являющейся Number
, Integer
или Double
.
Пока каждый из этих типов поддерживает интерфейс Comparable
, они также удовлетворяют первой части декларации. Это означает, что вы можете передать Number
для T
, и полученный код будет работать, если в списках присутствуют экземпляры Integer
и Double
. Если вы Integer
для T
, вы все равно можете использовать Double
, но Number
невозможно, потому что он больше не удовлетворяет T extends Comparable
(часть super
все равно будет работать).
Следующий шаг - понять, что выражение между static
и List
просто объявляет свойства типа T
, которые используются позже в коде. Таким образом, вам не нужно повторять эту длинную декларацию снова и снова. Это часть поведения метода (например, public
), а не часть фактического кода.