2009-10-08 14 views
1

J'essaie d'implémenter une méthode d'utilitaire de tri générique pour une liste d'objets de toute classe qui implémente MyInterface. Par Java API (http://java.sun.com/javase/6/docs/api/java/util/Collections.html), signature de la méthode Collections.sort() est:Création d'un objet Comparateur pour le tri de liste générique <? extends T> en utilisant Collections.sort()

public static <T> void sort(List<T> list, Comparator<? super T> c) 

Je ne sais pas si la liste avec un paramètre générique peut remplacer une "simple" Liste paramétrées, mais j'ai essayé:

static void mySort(List<? extends MyInterface> myList, SortCriteria mySortCriteria) { 
    Collections.sort(myList, new Comparator<? super MyInterface>() { 
     ... 
    }); 
} 

et a obtenu une erreur de compilation,

The type new Comparator(){} cannot extend or implement Comparator<? super MyInterface> 
A supertype may not specify any wildcard. 

Alors, je l'ai changé:

static void mySort(List<? extends MyInterface> myList, SortCriteria mySortCriteria) { 
    Collections.sort(myList, new Comparator<MyInterface>() { 
     ... 
    }); 
} 

Et il compile et fonctionne. Des bonnes explications?

+0

Quand vous dites * "quand je l'ai essayé" *, qu'avez-vous essayé exactement? Pouvez-vous poster du code? –

Répondre

2

Vous utilisez contravariance ici.

Fondamentalement, vous devez avoir un comparateur qui peut comparer deux éléments de la liste. Si la liste est de type T, cela signifie qu'elle doit être capable de comparer deux éléments de type T - mais si elle peut comparer deux éléments quelconques de type X où T est une sous-classe de X, alors ça ira aussi. Pour donner mon exemple préféré, si vous avez un comparateur qui peut comparer deux formes par zone, alors vous pouvez clairement utiliser cela pour comparer deux triangles - donc c'est bon de trier un List<Triangle> en utilisant AreaShapeComparator. Je ne suis pas sûr de ce que vous entendez par "quand je l'ai essayé" dans votre dernier paragraphe ... si vous pouviez donner un exemple court mais complet qui ne fonctionne pas, nous pouvons essayer d'expliquer pourquoi.

EDIT: D'accord, vous ne pouvez pas utiliser ? extends X ou ? extends Y dans une expression new - vous ne pouvez les utiliser dans le cadre d'une déclaration, soit d'une méthode, un type ou d'une variable. Lorsque vous construisez un objet nouvel, vous devez spécifier le type exact.

+0

@Eugene: Vous devez montrer * exactement * ce que vous avez essayé - pas seulement un seul extrait d'une ligne, mais tout le contexte. –

+0

J'ai édité la question - j'espère que c'est plus clair maintenant. Merci! –

1

Je ne comprends pas l'effet de cette contrainte sur Comparator

La contrainte dit que le comparateur doit être en mesure de comparer au moins le type générique des List, ou supertypes de celui-ci . Par exemple, il serait valide d'utiliser un Comaparator<Number> pour trier un List<Integer>. Si le Comparator est capable de comparer Number s, alors il est, bien sûr, capable de comparer Integer s.