2009-11-20 12 views
13

El siguiente me da un mensaje de error:Genéricos de Java: compareTo y "capture # 1-of?"

public static List<Comparable<?>> merge(Set<List<Comparable<?>>> lists) { 
    List<Comparable<?>> result = new LinkedList<Comparable<?>>(); 
    HashBiMap<List<Comparable<?>>, Integer> location = HashBiMap.create(); 

    int totalSize; 
    for (List<Comparable<?>> l : lists) { 
     location.put(l, 0); 
     totalSize += l.size(); 
    } 

    boolean first; 
    List<Comparable<?>> lowest; //the list with the lowest item to add 
    int index; 

    while (result.size() < totalSize) { 
     first = true; 

     for (List<Comparable<?>> l : lists) { 
      if (! l.isEmpty()) { 
       if (first) { 
        lowest = l; 
       } 
       else if (l.get(location.get(l)).compareTo(lowest.get(location.get(lowest))) <= 0) { //error here 
        lowest = l; 
       } 
      } 
     } 
     index = location.get(lowest); 
     result.add(lowest.get(index)); 
     lowest.remove(index); 
    } 
    return result; 
} 

El error es:

The method compareTo(capture#1-of ?) in the type Comparable<capture#1-of ?> is not applicable for the arguments (Comparable<capture#2-of ?>) 

lo que está pasando aquí? Hice el tipo de todo Comparable para poder llamar al .compareTo y ordenar esta lista. ¿Estoy usando genéricos incorrectamente?

+0

Algunos de esos deben ser , pero no tengo tiempo en este momento para ordenar esto en una respuesta. Si nadie más lo hago, volveré más tarde. – bmargulies

Respuesta

20

List<?> significa "Lista de cualquier cosa", por lo que dos objetos con este tipo no son lo mismo: uno podría ser una lista de String, la otra una lista de BigDecimal. Obviamente, esos no son lo mismo.

List<T> significa "Lista de todo pero cuando ve T otra vez, es lo mismo T".

Debe decirle al compilador cuando se refiere al mismo tipo en diferentes lugares. Proveedores:

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] Por lo tanto, ¿qué significa <T extends Comparable<? super T>> List<T>? La primera parte define un tipo T con las siguientes propiedades: Debe implementar la interfaz Comparable<? super T> (o Comparable<X> donde X también se define en términos de T).

? super T significa que el tipo que admite el Comparable debe ser T o uno de sus súper tipos.

Imagine por un momento esta herencia: Double extends Integer extends Number. Esto no es correcto en Java, pero imagine que Double es solo un Integer más una parte fraccionaria. En este escenario, un Comparable que funciona para Number también funciona para Integer y Double ya que ambos derivan de Number. Entonces Comparable<Number> satisfaría la parte super para T siendo Number, Integer o Double.

Siempre que cada uno de estos tipos sea compatible con la interfaz Comparable, también cumplen la primera parte de la declaración. Esto significa que puede pasar Number para T y el código resultante también funcionará cuando haya instancias Integer y Double en las listas. Si Integer para T, aún puede usar Double, pero Number ya no es posible porque ya no satisface T extends Comparable (la parte super aún funcionaría).

El siguiente paso es comprender que la expresión entre static y List acaba de declarar las propiedades del tipo T que se utiliza más adelante en el código. De esta manera, no tienes que repetir esta larga declaración una y otra vez. Es parte del comportamiento del método (como public) y no forma parte del código real.

+0

Me sale el error de que 'T no se puede resolver a un tipo'. –

+0

He solucionado mi respuesta. Este código compilaSi obtienes errores cuando los usas, elimina el '' pero debería funcionar. Ah, y reemplace 'LinkedList' con' ArrayList'. Es mucho más rápido y usa mucha menos memoria. –

+0

¿Puede explicar exactamente qué significa '>' significa? –