Обобщения Java: подпись Collections.max() и компаратор
Я понимаю принцип get и put для коллекций: если метод принимает коллекцию, в которую он будет записывать тип T, параметр должен быть Collection<? super T>
тогда как если он будет читать тип T из, параметр должен быть Collection<? extends T>
,
Но может кто-нибудь объяснить, пожалуйста, Collections.max()
подпись:
public static <T> T max(Collection<? extends T> coll,
Comparator<? super T> comp)
В частности, почему это Comparator<? super T>
вместо Comparator<? extends T>
?
3 ответа
Mnemonic PECS Джоша Блоха полезен здесь. Это означает:
Режиссер extends
Потребитель super
Это означает, что когда параметризованный тип, передаваемый методу, будет создавать экземпляры T
(они будут каким-то образом извлечены из него), ? extends T
следует использовать, так как любой экземпляр подкласса T
также T
,
Когда параметризованный тип, передаваемый методу, будет использовать экземпляры T
(они будут переданы ему, чтобы сделать что-то), ? super T
следует использовать, потому что экземпляр T
может быть законно передан любому методу, который принимает некоторый супертип T
, Comparator<Number>
может быть использован на Collection<Integer>
, например. ? extends T
не будет работать, потому что Comparator<Integer>
не мог работать на Collection<Number>
,
Изменить: Чтобы уточнить немного больше о получении / сдаче (производить / потреблять):
public T something();
^
Выше приведен метод, который производит T
,
public void something(T t);
^
Выше приведен метод, который потребляет T
,
"Режиссер extends
Потребитель super
"применяется к тому, как метод, которому передается параметризованный объект, будет использовать этот объект. Collections.max()
элементы будут получены из Collection
так что это производитель. Эти элементы будут переданы в качестве аргументов в метод на Comparator
Значит, это потребитель.
Компаратор потребляет пару Ts и выдает int. Коллекция производит Ts, которую потребляет компаратор.
Супер потребляет, расширяет, производит.
Относительно принципа "получи и положи", получи, произведи и положи, потребляет.
Компаратор должен быть в состоянии взять T
в качестве аргумента.