Bir Kümeyi Java'daki Bir Listeye nasıl sıralayabilirim?


169

Java'da bir tane var Setve sıralı bir hale getirmek istiyorum List. java.util.CollectionsPakette bunu benim için yapacak bir yöntem var mı ?

Yanıtlar:


214

OP tarafından verilen cevap en iyisi değildir. Yeni List ve gereksiz yeni bir dizi oluşturduğundan verimsizdir . Ayrıca, genel dizilerle ilgili türdeki güvenlik sorunları nedeniyle "denetlenmeyen" uyarılar oluşturur.

Bunun yerine, şöyle bir şey kullanın:

public static
<T extends Comparable<? super T>> List<T> asSortedList(Collection<T> c) {
  List<T> list = new ArrayList<T>(c);
  java.util.Collections.sort(list);
  return list;
}

İşte bir kullanım örneği:

Map<Integer, String> map = new HashMap<Integer, String>();
/* Add entries to the map. */
...
/* Now get a sorted list of the *values* in the map. */
Collection<String> unsorted = map.values();
List<String> sorted = Util.asSortedList(unsorted);

3
Teşekkürler! SuppressWarnings her zaman beni rahatsız etti.
Jeremy Stein

4
@sunleo UtilSınıf, asSortedList()yazdığım yöntemi içeren sınıftır . Başka bir deyişle, Utilsınıfı kendiniz yazar ve bu kodu içine koyarsınız.
erickson

1
ha ha onun java.util tamam teşekkür ederim gibi varsayılan paketinden düşündüm.
sunleo

3
Bu hoş bir genel Utility işlevi olabilir, ama gerçek şu ki, hala verimli değildir. Başlangıçta doğru sette setinizin bulunduğundan emin olarak yerinde sıralama yapmayı düşünün. Ayrıca TreeSet'in verilerinizin doğrudan kapsayıcısı olarak kullanılmasını da düşünün. Verilerinizin benzersiz olması gerekiyorsa ve bir Kümeye ihtiyacınız varsa, TreeSet'i kullanın, bir swatta iki sinek yakalar.
YoYo

1
Yalnızca en iyi yanıtı okuyan kişilere not olarak: Java 8'in akışlarını kullanan aşağıdaki nschum'un cevabına bir göz atın. Java 8 kullanabiliyorsanız, deneyin. daha esnek ve verimlidirler.
Felk

74

Sıralama kümesi:

return new TreeSet(setIWantSorted);

veya:

return new ArrayList(new TreeSet(setIWantSorted));

Bu benim ilk düşüncemdi, ama asker bir liste istedi
Alex B

@Alex: Bu yaklaşım hala kullanılabilir; return new ArrayList (yeni TreeSet (setIWantSorted))
Jonik

1
Aslında bu çözümü kullandım, ama bunu tavsiye etmem. TreeSet'in belgelerine göre (bkz. Download.oracle.com/javase/1.4.2/docs/api/java/util/… ) eşittir () yöntemi yerine CompareTo () yöntemini etkili bir şekilde kullanır; sette aynı () sonucuna sahip iki nesne varsa, bunlar kopya olarak görülecek ve bu nedenle TreeSet'e eklenmeyecektir. Dikkat.
fwielstra

24
@fwielstra: Girdi de bir olduğu için girdide eşit olan nesnelere nasıl sahip olabilirsiniz Set?
ryanprayogo

2
@ryanprayogo Bahsetmeye değer , sadece s değil new TreeSet, Collections kabul ediyor Set. Bu sorunun cevabını okuyan herkes Set, asıl sorunun sorduğu soru olsa da, bir
Chris

44
List myList = new ArrayList(collection);
Collections.sort(myList);

… Ancak hile yapmalı. Varsa, Generics ile lezzet katın.


Topluluğa bağışlamak istediğim yararlı bir pasajım vardı. Bilgileri aradığımda bulamadım. Bir sonraki kişinin işini kolaylaştırmaya çalışıyordum. stackoverflow.com/questions/18557/…
Jeremy Stein

1
Evet, elbette, ama sağladığınız bağlantı aslında gerçek sorulardan bahsediyor (yani cevabı olmayanlar, sonra bul). Buradaki sorunuz sadece cevap vermekti ... Aslında yüzlerce soru girip kendime cevap verebilirdim; konu o değil!
Seb

5
@Seb: Katılmıyorum. Bu soruda yanlış bir şey görmüyorum. Açıkçası son derece basit bir soru değildi ve şimdi daha önce olduğundan daha iyi bir yol biliyor!
Michael Myers

3
O was gerçek bir soru, ancak Google eteğine geldi sonra ben cevap buldum. Stackoverflow o sırada mevcut değildi. Web sitemde yayınladım ve başka birine yardımcı oldu, bu yüzden burada yararlı olabileceğini düşündüm.
Jeremy Stein

Bonus: Ve kendi nesne türünüzü Comparablesıralıyorsanız, compareToyöntemi her zaman uygulayabilir ve geçersiz kılabilirsiniz .
nabster

42

Java 8'in Akışları ile şu şekilde yapabilirsiniz:

mySet.stream().sorted().collect(Collectors.toList());

veya özel bir karşılaştırıcı ile:

mySet.stream().sorted(myComparator).collect(Collectors.toList());

9

Sıralama uygulaması sağlamak için Karşılaştırıcı veya Karşılaştırılabilir arabirimi kullanmak her zaman güvenlidir (nesne ilkel veri türleri için bir String veya Wrapper sınıfları değilse). Çalışanları ada göre sıralamak için bir karşılaştırıcı uygulamasına örnek olarak

    List<Employees> empList = new LinkedList<Employees>(EmpSet);

    class EmployeeComparator implements Comparator<Employee> {

            public int compare(Employee e1, Employee e2) {
                return e1.getName().compareTo(e2.getName());
            }

        }

   Collections.sort(empList , new EmployeeComparator ());

Karşılaştırıcı, aynı nesne üzerinde farklı sıralama algoritması (emp adı, emp maaşı vb.) Gerektiğinde yararlıdır. Gerekli modda Karşılaştırılabilir arabirim kullanılarak tek modlu sıralama yapılabilir.


5

Bunu yapmak için tek bir yöntem yok. Bunu kullan:

@SuppressWarnings("unchecked")
public static <T extends Comparable> List<T> asSortedList(Collection<T> collection) {
  T[] array = collection.toArray(
    (T[])new Comparable[collection.size()]);
  Arrays.sort(array);
  return Arrays.asList(array);
}

Collections.sort işlevi de var, ama aynı şeyi yaptığını düşünüyorum. Yine de +1.
CookieOfFortune

1
Collections.sort bir listeyi parametre olarak alır.
Jeremy Stein

3

ArrayListKümeyi ArrayListkullanarak sıralayabileceğiniz bir dizine dönüştürebilirsiniz Collections.sort(List).

İşte kod:

keySet = (Set) map.keySet();
ArrayList list = new ArrayList(keySet);     
Collections.sort(list);

3
TreeSet sortedset = new TreeSet();
sortedset.addAll(originalset);

list.addAll(sortedset);

burada orijinal küme = sıralanmamış küme ve liste = döndürülecek liste


TreeSet, listeyi de kaldırır ve bunu varsaymazsanız yanlış sonuca neden olabilir.
anthonymonori

2

@Jeremy Stein Aynı kodu uygulamak istedim. Ben de kümeyi listeye sıralamak istedim, bu yüzden Set I dönüştürdüğüm set değerlerini kullanmak yerine List'e dönüştürdüm ve bu listeyi bir değişkenle sıralayın. Bu kod bana yardımcı oldu,

set.stream().sorted(Comparator.comparing(ModelClassName::sortingVariableName)).collect(Collectors.toList());

0

Yukarıda kabul edilen cevaptan daha pratik bulduğum bu kodu kullanıyorum:

List<Thing> thingList = new ArrayList<>(thingSet);
thingList.sort((thing1, thing2) -> thing1.getName().compareToIgnoreCase(thing2.getName()));
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.