2009-11-20 4 views
13

Di seguito mi dà un messaggio di errore:Java Generics: compareTo e "cattura # 1 di?"

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; 
} 

L'errore è:

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

cosa sta succedendo qui? Ho fatto il tipo di tutto Comparable così ho potuto chiamare .compareTo e ordinare questa lista. Sto usando i farmaci generici in modo errato?

+0

Alcuni di quelli devono essere , ma non ho tempo in questo minuto per ordinare questo in una risposta. Se nessun altro tornerò più tardi. – bmargulies

risposta

20

List<?> significa "Lista di nulla", così due oggetti con questo tipo non sono gli stessi: Si potrebbe essere un elenco di String, l'altro un elenco di BigDecimal. Ovviamente, quelli non sono la stessa cosa.

List<T> significa "Elenco dei nulla, ma quando si vede T ancora una volta, è lo stesso T".

È necessario indicare al compilatore quando si intende lo stesso tipo in luoghi diversi. Prova:

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] Che cosa significa <T extends Comparable<? super T>> List<T>? La prima parte definisce un tipo T con le seguenti proprietà: È necessario implementare l'interfaccia Comparable<? super T> (o Comparable<X> dove è anche definito in termini di T).

? super T significa che il tipo che supporta Comparable deve T o uno dei suoi super tipi.

Immaginate per un momento questa eredità: Double extends Integer extends Number. Questo non è corretto in Java, ma immagina che Double sia solo uno Integer più una parte frazione. In questo scenario, un Comparable che funziona per Number funziona anche per Integer e Double poiché entrambi derivano da Number. Quindi Comparable<Number> soddisferebbe la parte super per TNumber, Integer o Double.

Fintantoché ognuno di questi tipi supporta l'interfaccia Comparable, soddisfa anche la prima parte della dichiarazione. Ciò significa che è possibile passare in Number per T e il codice risultante funzionerà anche quando ci sono istanze Integer e negli elenchi. Se si Integer per T, è ancora possibile utilizzare Double ma Number non è possibile perché non soddisfa più T extends Comparable (la parte super funzionerebbe comunque).

Il passo successivo è capire che l'espressione tra static e List solo dichiara le proprietà del tipo T che viene utilizzato in seguito nel codice. In questo modo, non devi ripetere questa lunga dichiarazione più e più volte. Fa parte del comportamento del metodo (come public) e non fa parte del codice effettivo.

+0

Viene visualizzato l'errore che "T non può essere risolto in un tipo". –

+0

Ho risolto la mia risposta. Questo codice viene compilato.Si ottengono errori quando lo si utilizza, rimuovere il '' ma dovrebbe funzionare. Oh, e sostituisci 'LinkedList' con' ArrayList'. È molto più veloce e utilizza molta meno memoria. –

+0

Puoi spiegare esattamente cosa significa ">"? –