Обобщения Java: подпись Collections.max () и компаратор - PullRequest
25 голосов
/ 12 февраля 2010

Я понимаю принцип get and put для коллекций: если метод принимает коллекцию, в которую будет записан тип T, параметр должен быть Collection<? super T>, тогда как если он будет читать введите T from, параметр должен быть 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 ]

65 голосов
/ 12 февраля 2010

мнемоника Джоша Блоха PECS полезна здесь. Он обозначает:

Производитель extends, Потребитель super

Это означает, что когда параметризованный тип, передаваемый методу, будет создавать экземпляров T (они будут каким-то образом извлечены из него), следует использовать ? extends T, поскольку любой экземпляр подкласса T также является T.

Когда параметризованный тип, передаваемый методу, будет потреблять экземпляров T (они будут переданы ему для выполнения каких-либо действий), следует использовать ? super T, поскольку экземпляр T может быть законно передан любому методу, который принимает некоторый супертип T. Например, Comparator<Number> можно использовать для Collection<Integer>. ? extends T не будет работать, потому что Comparator<Integer> не может работать на Collection<Number>.

Edit: Чтобы уточнить немного больше о получении / сдаче (производстве / потреблении):

public T something();
       ^

Выше приведен метод, который производит T.

public void something(T t);
                      ^

Выше приведен метод, который потребляет T.

«Производитель extends, Потребитель super» применяется к тому, как метод, которому передается параметризованный объект, будет использовать этот объект. В случае Collections.max() элементы будут извлечены из Collection, так что это производитель. Эти элементы будут переданы в качестве аргументов методу Comparator, поэтому он является потребителем.

1 голос
/ 12 февраля 2010

Компаратор потребляет пару Ts и выдает int. Коллекция производит Ts, потребляемый компаратором.

Супер потребляет, расширяет производит.

Относительно принципа «получи и положи», получи, положи и положи.

0 голосов
/ 12 февраля 2010

Компаратор должен иметь возможность принимать T в качестве аргумента.

...