2010-10-13 28 views
12

Quelle est la "bonne" (et pourquoi?) Solution pour obtenir un List à partir d'un Set et triés par rapport à un donné Comparator?Comment obtenir liste de Set et comparateur

+0

Cette question n'est pas claire. Par exemple, je peux obtenir une liste d'un ensemble et un comparateur en ignorant le comparateur. C'est une "bonne" solution ... en ce sens qu'elle est plus rapide que les solutions utilisant le comparateur. –

+0

@Stephen Je mets à jour ma question –

+1

Êtes-vous sûr de vouloir une liste? Peut-être qu'un SortedSet ferait l'affaire. –

Répondre

11
Set<Object> set = new HashSet<Object>(); 

// add stuff 

List<Object> list = new ArrayList<Object>(set); 
Collections.sort(list, new MyComparator()); 
+0

vient d'ajouter COllections.sort() après cela. –

+0

Mauvaise réponse, cela ne fonctionnera pas car le constructeur ArrayList ne trie rien, vous n'avez même pas utilisé votre comparateur, alors comment sera-t-il trié? Utilisez Collections.sort() ou TreeSet, comme dans les autres réponses. – iirekm

+0

Avoir corrigé la réponse pour inclure l'appel à trier. –

6

Juste le construire. Le ArrayList a un constructor taking another Collection.

Set<Foo> set = new TreeSet<Foo>(new FooComparator<Foo>()); 
// Fill it. 

List<Foo> list = new ArrayList<Foo>(set); 
// Here's your list with items in the same order as the original set. 
0

Voici comment obtenir un List quand vous avez un Set:

List list = new ArrayList(set); 

Je ne sais pas ce que vous attendez à voir avec le Comparator. Si le Set est trié, la liste contiendra les éléments dans l'ordre trié.

+1

Évidemment, il s'attend à utiliser le comparateur pour obtenir une liste triée, ce qui implique que l'ensemble n'est pas trié. À quoi d'autre utiliseriez-vous un comparateur? Donc, il devrait soit passer par un ensemble trié ou trier la liste après l'avoir peuplé. –

+0

@Christoffer Hammarström - ou trier quand/en insérant les éléments un par un: tri d'insertion. – Ishtar

+0

@Ishtar: Qu'est-ce qui se passe si vous passez par un ensemble trié, ma première suggestion. –

2

Soit:

Set<X> sortedSet = new TreeSet<X>(comparator); ... 
List<X> list = new ArrayList<X>(sortedSet); 

ou:

Set<X> unsortedSet = new HashSet<X>(); ... 
List<X> list = new ArrayList<X>(unsortedSet); 
Collections.sort(list, comparator); 
1

En supposant que vous commencez avec un ensemble non triés ou un ensemble trié sur un ordre différent, ce qui suit est probablement l'hypothèse la plus efficace que vous avez besoin d'une liste modifiable.

Set<T> unsortedSet = ... 
List<T> list = new ArrayList<T>(unsortedSet); 
Collections.sort(list, comparator); 

Si une liste non modifiable est acceptable, ce qui suit est une peu plus rapide:

Set<T> unsortedSet = ... 
T[] array = new T[unsortedSet.size()]; 
unsortedSet.toArray(array); 
Arrays.sort(array, comparator); 
List<T> list = Arrays.asList(array); 

Dans la première version, Collections.sort(...) copie le contenu de la liste dans un tableau, trie le tableau, et copie les éléments triés de nouveau à la liste. La seconde version est plus rapide car elle n'a pas besoin de copier les éléments triés. Mais pour être honnête, la différence de performance n'est probablement pas significative. En effet, au fur et à mesure que les tailles des ensembles d'entrée augmentent, les performances seront dominées par le temps O(NlogN) pour effectuer le tri. Les étapes de copie sont O(N) et diminueront en importance à mesure que N croît.

+0

Votre version avec Arrays.sort n'optimise en fait pas beaucoup (ou même rien), car Collections.sort() contient déjà un code similaire: Object [] a = list.toArray(); Arrays.sort (a, (Comparateur) c); ListIterator i = list.listIterator(); pour (int j = 0; j iirekm

+0

@iirekm - l'utilisation de 'Arrays.asList (array)' évite la copie effectuée en utilisant l'itérateur de liste. –

+0

Aaah, cette copie supplémentaire peut être importante uniquement pour les très grands ensembles de données. – iirekm