Comment mettre en œuvre un générique de `max(Comparable à un, Comparable b) la fonction en Java?
Je suis en train d'écrire un générique max la fonction qui prend deux Comparable
s.
Pour l'instant j'ai
public static <T extends Comparable<?>> T max(T a, T b) {
if (a == null) {
if (b == null) return a;
else return b;
}
if (b == null)
return a;
return a.compareTo(b) > 0 ? a : b;
}
Cela ne compile avec
The method compareTo(capture#5-of ?) in the type Comparable<capture#5-of ?> is not applicable for the arguments (T)
Ce que je pense c'est de dire, c'est que le ?
dans Comparable<?>
peut être interprété comme un type de paramètre a, et un autre pour le paramètre b, de sorte qu'ils ne peuvent pas être comparés.
Comment dois-je creuser moi-même de sortir de ce trou?
- Dans le
if(a==null)
bloc, il n'est pas nécessaire pour le imbriquée si la clause. Réduire le bloc dereturn b;
donne le même résultat (null
quandb
estnull
,b
contraire). - Voir org.apache.commons.lang3.ObjectUtils.comparez
Vous devez vous connecter pour publier un commentaire.
Pour de meilleurs résultats, vous devez utiliser
public static <T extends Comparable<? super T>> T max(T a, T b)
.Le problème avec
<T extends Comparable<?>>
est que cela, dit que le type T est comparable à un certain type, mais vous ne savez pas ce que le type est. Bien sûr, le bon sens voudrait qu'une classe qui implémente Comparable devrait être en mesure d'être comparable à au moins lui-même (c'est à dire être en mesure de comparer les objets de son propre type), mais il n'y a techniquement, rien n'empêche de catégorie A à partir de la mise en œuvre deComparable<B>
, où A et B n'ont rien à voir les uns avec les autres.<T extends Comparable<T>>
résout ce problème.Mais il y a un problème subtil que. Supposons que la classe X implémente
Comparable<X>
, et j'ai une classe de Y qui s'étend X. Alors la classe Y implémente automatiquementComparable<X>
par héritage. Classe Y peut pas également de mettre en œuvreComparable<Y>
parce qu'une classe ne peut pas mettre en œuvre une interface à deux reprises avec différents paramètres de type. Ce n'est pas vraiment un problème, puisque les instances de Y sont des instances de X, alors Y est comparable à toutes les instances de Y. Mais le problème est que vous ne pouvez pas utiliser le type Y avec votre<T extends Comparable<T>> T max(T a, T b)
fonction, parce que Y ne pas mettre en œuvreComparable<Y>
. Les limites sont trop strictes.<T extends Comparable<? super T>>
résout le problème, parce que c'est suffisant pour que T est comparable à certains supertype de T (qui comprendrait toutes les T des cas). Rappel de la règle PECS - producteurextends
, de la consommationsuper
- dans ce cas,Comparable
est un consommateur (il prend un objet à des fins de comparaison), de sortesuper
de sens.C'est le type de limites utilisé par tous les tri et de commande des fonctions de la bibliothèque Java.
Vous obtenez cette erreur, car
Comparable<?>
dit en gros que c'est comparable à quelque chose sans rien préciser. Vous devriez écrireComparable<T>
au lieu de cela, de sorte que le compilateur sache que le type T est comparable à lui-même.Pour répondre à ma propre question de l'généré liens connexes - ce qui semble être un subtil double de Plaisir avec Java génériques , bien que je pense que vous ne pouvez pas me blâmer de ne pas la trouver, étant donné le titre!
La solution la plus simple semble être
J'ai écrit une classe utilitaire pour cela. Peut-être que vous le trouverez utile (la bibliothèque est Open Source):
http://softsmithy.sourceforge.net/lib/docs/api/org/softsmithy/lib/util/Comparables.html
Page d'accueil:
http://www.softsmithy.org
Télécharger:
http://sourceforge.net/projects/softsmithy/files/softsmithy/
Maven:
C'est offten mieux arriver déjà mis en œuvre la norme iso créer possède. Voir à Min /Max fonction à deux Comparables. La plus simple est
org.apache.commons.lang.ObjectUtils
: