java generics comparator

Genéricos de Java: firma Collections.max() y comparador



generics comparator (3)

Entiendo el principio get y put para colecciones: si un método toma una colección en la que escribirá un tipo T, el parámetro tiene que ser Collection<? super T> Collection<? super T> , mientras que si lee un tipo T desde, el parámetro tiene que ser Collection<? extends T> Collection<? extends T> .

Pero podría alguien explicar la firma Collections.max() :

public static <T> T max(Collection<? extends T> coll, Comparator<? super T> comp)

En particular, ¿por qué es Comparator<? super T> Comparator<? super T> lugar de Comparator<? extends T> Comparator<? extends T> ?


El PECS mnemotécnico de Josh Bloch es útil aquí. Lo que representa:

El productor se extends , el consumidor super

Esto significa que cuando un tipo parametrizado se pasa a un método producirá instancias de T (se recuperarán de alguna manera) ? extends T ? extends T debe usar ? extends T , ya que cualquier instancia de una subclase de T también es T

Cuando un tipo parametrizado que se pasa a un método consumirá instancias de T (se pasarán a él para hacer algo) ? super T debe usarse ? super T porque una instancia de T puede pasarse legalmente a cualquier método que acepte algún supertipo de T Un Comparator<Number> podría usarse en una Collection<Integer> , por ejemplo. ? extends T ? extends T no funcionaría, porque un Comparator<Integer> no podría operar en una Collection<Number> .

Editar: Para aclarar un poco más sobre get / put (producir / consumir):

public T something(); ^

Lo anterior es un método que produce T

public void something(T t); ^

Lo anterior es un método que consume T

"Producer extends , Consumer super " se aplica a cómo el método al que se va a pasar un objeto parametrizado va a usar ese objeto. En el caso de Collections.max() , los elementos se recuperarán de la Collection , por lo que es un productor. Esos elementos se pasarán como argumentos al método en Comparator , por lo que es un consumidor.


El Comparador consume un par de Ts y produce un int. La colección produce los Ts que consume el comparador.

Súper consume, extiende produce.

En relación con el principio get y put, get produce y pone consume.


El comparador debe poder tomar una T como argumento.