2010-10-13 23 views
12

Bir Set'ten Set elde etmek ve belirli bir Comparator'e göre sıralamak için "iyi" (ve neden?) çözüm nedir?Set ve Karşılaştırıcı Listesinden Nasıl Alınır?

+0

Bu soru belirsizdir. Örneğin, Karşılaştırıcıyı göz ardı ederek bir Küme ve Karşılaştırıcıdan bir Liste alabilirim. Karşılaştırıcıyı kullanan çözümlerden daha hızlı olması açısından "iyi" bir çözümdür. –

+0

@Stephen Soruyu çözme –

+1

Listeye ihtiyacınız var mı? Belki bir SortedSet yapardı. –

cevap

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

// add stuff 

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

Sadece bundan sonra COllections.sort() eklendi. –

+0

Yanlış cevap, bu ArrayList yapıcısı hiçbir şey sıralamıyor, bu yüzden Karşılaştırıcı nasıl kullanılmadı, bu yüzden nasıl sıralanır olacak çalışmaz? Diğer yanıtlarda olduğu gibi Collections.sort() veya TreeSet'i kullanın. – iirekm

+0

Yanıtlanacak aramayı dahil etmek için cevabı düzelttim. –

6

Sadece yapılandırın. ArrayList, constructor taking another Collection'a sahiptir. Eğer Comparator ilgisi beklediğiniz emin değil

List list = new ArrayList(set); 

:

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

Bu, bir Set varken bir List edinmektir. Set sıralanırsa, liste öğeleri sıralı sırada içerecektir.

+1

Açıkçası, karşılaştırmalı listeyi almak için karşılaştırıcıyı kullanmayı ve kümenin sıralanmamış olduğunu ima eder. Bir karşılaştırıcıyı başka ne kullanırdınız? Bu yüzden ya sıralı bir kümeden geçmeli ya da listeyi doldurduktan sonra sıralamalıdır. –

+0

@Christoffer Hammarström - veya öğeleri teker teker ekleyerek sıralayın: ekleme sıralama. – Ishtar

+0

@Ishtar: Sıralı bir setten ilk önerimi yaparsanız ne olur? –

2

Ya:

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

ya: Bir sıralanmamış seti veya farklı bir sırayla sıralanır seti ile başlamak varsayarsak

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

aşağıdaki muhtemelen varsayarak en verimli Değiştirilebilir bir Liste gerektirir. degistiremeyeceginiz Liste kabul edilebilir ise

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

, ardından aşağıdaki biraz daha hızlıdır: İlk versiyonda

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

, Collections.sort(...) kopya bir diziye liste içeriği, dizi ve kopyalarını sıralar sıralı öğeler listeye geri döndü. İkinci sürüm daha hızlıdır çünkü sıralanan öğeleri kopyalamaya gerek yoktur. Dürüst olmak gerekirse, performans farkı muhtemelen önemli değil. Gerçekten de, giriş seti boyutları büyüdükçe, performansın sıralaması O(NlogN) tarafından belirlenir. Kopyalama adımları O(N)'dur ve N büyürken önemini azaltır.

+0

Arrays.sort ile sürümünüz aslında çok fazla (veya hiç bir şey) optimize etmez, çünkü Collections.sort() zaten benzer kod içerir: Nesne [] a = list.toArray(); Arrays.sort (a, (Karşılaştırıcı) c); ListIterator i = list.listIterator(); Için (int j = 0; j iirekm

+0

@iirekm - 'Arrays.asList (dizi)' kullanarak, liste yineleyicisi kullanılarak gerçekleştirilen kopyalamayı önler. –

+0

Aaah, bu fazladan kopyalama sadece çok büyük veri kümeleri için önemli olabilir. – iirekm

İlgili konular