2008-09-12 5 views
18

Je suis convertir une application à utiliser Java 1.5 et ont trouvé la méthode suivante:Puis-je convertir le code suivant pour utiliser des génériques?

/** 
    * Compare two Comparables, treat nulls as -infinity. 
    * @param o1 
    * @param o2 
    * @return -1 if o1<o2, 0 if o1==o2, 1 if o1>o2 
    */ 
    protected static int nullCompare(Comparable o1, Comparable o2) { 
    if (o1 == null) { 
     if (o2 == null) { 
     return 0; 
     } else { 
     return -1; 
     } 
    } else if (o2 == null) { 
     return 1; 
    } else { 
     return o1.compareTo(o2); 
    } 
    } 

Idéalement je voudrais faire la méthode prendre deux Comparables du même type, il est possible de convertir cela et comment ?

Je pensais que ce qui suit ferait l'affaire:

protected static <T extends Comparable> int nullCompare(T o1, T o2) { 

mais il n'a pas réussi à se débarrasser d'un avertissement dans IntelliJ « Appel non contrôlé à « compareTo (T) » en tant que membre de type raw « java .lang.Comparable ' » sur la ligne:

return o1.compareTo(o2); 

Répondre

21

Modifier à:

protected static <T extends Comparable<T>> int nullCompare(T o1, T o2) { 

Vous avez besoin parce que Compara ble est lui-même un type générique.

+0

Aargh! Je n'arrive pas à croire que j'étais si proche –

+0

Ça remonte tout le monde. – jodonnell

+0

Êtes-vous sûr que T s'étend Comparable est vrai? Il semble que T s'étend comparable serait plus correct? – cletus

5

Voici un cas étrange:

static class A { 
    ... 
} 

static class B extends A implements Comparable<A> { 
    public int compareTo(A o) { 
     return ...; 
    } 
} 

Heureusement code comme celui ci-dessus est rare, mais nullCompare() ne soutiendra pas la comparaison des hôtes à moins il est indiqué que Comparable peut demander à T ou tout superclasse de celui-ci:

protected static <T extends Comparable<? super T>> int nullCompare(T o1, T o2) { 

Même si la plupart des gens ne bénéficieront jamais du tweak ci-dessus, il peut être utile lors de la conception d'API pour les bibliothèques exportées.

0

Je ne suis pas sûr que générique de cette méthode ait du sens. Actuellement, la méthode fonctionne sur n'importe quel type de comparable; Si vous le générez, vous devrez l'implémenter (avec exactement le même code) plusieurs fois. Parfois, il est possible de comparer deux objets qui n'ont pas d'ancêtre commun, et aucune version générique ne le permettra.

En ajoutant des génériques, vous n'ajouterez aucune sécurité au code; tout problème de sécurité se produira dans l'appel à comparer. Ce que je suggère est simplement de supprimer l'avertissement. Cela ne vous avertit pas vraiment de quelque chose d'utile.

2

Impossible de modifier, donc je dois poster ma réponse.

Vous devez déclarer le paramètre de type imbriqué puisque Comparable est générique.

protected static <T extends Comparable<? super T>> int nullCompare(T o1, T o2) { 

S'il vous plaît noter que Comparable <? super T>, ce qui rend plus flexible. Vous verrez la même définition de méthode sur Collections.sort

public static <T extends Comparable<? super T>> void sort(List<T> list) { 
0

Pour le rendre encore plus générale, vous pourriez même lui permettre de travailler pour deux types différents. = P

/** 
    * Compare two Comparables, treat nulls as -infinity. 
    * @param o1 
    * @param o2 
    * @return -1 if o1&lt;o2, 0 if o1==o2, 1 if o1&gt;o2 
    */ 
    protected static <T> int nullCompare(Comparable<? super T> o1, T o2) { 
    if (o1 == null) { 
     if (o2 == null) { 
     return 0; 
     } else { 
     return -1; 
     } 
    } else if (o2 == null) { 
     return 1; 
    } else { 
     return o1.compareTo(o2); 
    } 
    } 
Questions connexes