Génériques Java: compareTo et "capture # 1-of?"
La suite me donne un message d'erreur:
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'erreur est:
The method compareTo(capture#1-of ?) in the type Comparable<capture#1-of ?> is not applicable for the arguments (Comparable<capture#2-of ?>)
Ce qui se passe ici? J'ai fait le type de tout Comparable
si je pouvais l'appeler .compareTo
et trier cette liste. Suis-je utiliser les génériques de façon incorrecte?
source d'informationauteur Nick Heiner
Vous devez vous connecter pour publier un commentaire.
List<?>
signifie "Liste de tout", de sorte que deux objets de ce type ne sont pas les mêmes: On peut être une liste deString
l'autre une liste deBigDecimal
. Évidemment, ce ne sont pas les mêmes.List<T>
signifie "Liste de rien, mais quand vous voyezT
encore une fois, c'est la mêmeT
".Vous devez indiquer au compilateur si vous parlez du même type dans des endroits différents. Essayez:
[EDIT] Donc, ce n'est
<T extends Comparable<? super T>> List<T>
veux dire? La première partie définit un typeT
avec les propriétés suivantes: Il doit implémenter l'interfaceComparable<? super T>
(ouComparable<X>
oùX
est également défini en termes deT
).? super T
signifie que le type qui l'Comparable
supports doiventT
ou l'un de ses super-types.Imaginez un instant cet héritage:
Double extends Integer extends Number
. Ce n'est pas correct en Java, mais imaginez queDouble
est juste unInteger
en plus d'une fraction de la partie. Dans ce scénario, unComparable
qui fonctionne pourNumber
fonctionne également pour lesInteger
etDouble
depuis proviennent tous deuxNumber
. DoncComparable<Number>
satisfaire lessuper
partie pourT
êtreNumber
Integer
ouDouble
.Aussi longtemps que chacun de ces types de support de la
Comparable
interface, qu'ils respectent également la première partie de la déclaration. Cela signifie, vous pouvez passer dansNumber
pourT
et le code résultant peut également il y aInteger
etDouble
cas dans les listes. Si vousInteger
pourT
vous pouvez toujours utiliserDouble
maisNumber
n'est pas possible car il n'est pas satisfaitT extends Comparable
plus (lesuper
partie va continuer à travailler, tout de même).La prochaine étape est de comprendre que l'expression entre
static
etList
déclare simplement les propriétés du typeT
qui est utilisé plus tard dans le code. De cette façon, vous n'avez pas à répéter cette longue déclaration, encore et encore. C'est le comportement de la méthode (commepublic
) et ne fait pas partie du code.