Liste yineleyicileri, her şeyden önce listenin öğelerini listenin iç düzeninde almanızı garanti eder ( ekleme siparişi olarak da bilinir ). Daha spesifik olarak, öğeleri eklediğiniz sırayla veya listeyi nasıl manipüle ettiğinizle ilgilidir. Sıralama, veri yapısının manipülasyonu olarak görülebilir ve listeyi sıralamanın birkaç yolu vardır.
Şahsen gördüğüm şekilde, fayda sırasına göre yolları sıralayacağım :
1. Bunun yerine Set
veya Bag
koleksiyonları kullanmayı düşünün
NOT: Bu seçeneği en üste koydum çünkü normalde yine de yapmak istediğiniz şey budur.
Sıralanmış bir küme koleksiyonu ekleme sırasında otomatik olarak sıralar , yani koleksiyona öğeler eklerken sıralamayı yapar. Ayrıca manuel olarak sıralamanız gerekmediği anlamına gelir.
Ayrıca, yinelenen öğeler hakkında endişelenmenize (veya sahip olmanıza) gerek olmadığından eminseniz, TreeSet<T>
bunun yerine bunu kullanabilirsiniz . Bir listeden beklediğiniz gibi uygular SortedSet
ve NavigableSet
arayüzler yapar ve çalışır:
TreeSet<String> set = new TreeSet<String>();
set.add("lol");
set.add("cat");
// automatically sorts natural order when adding
for (String s : set) {
System.out.println(s);
}
// Prints out "cat" and "lol"
Doğal sıralamayı istemiyorsanız, a alan yapıcı parametresini kullanabilirsiniz Comparator<T>
.
Alternatif olarak, kullanabileceğiniz MULTISETS (olarak da bilinir Çanta ) , bu ise Set
bunun yerine, yinelenen öğe izin verdiğini ve bunların üçüncü parti uygulama vardır. En önemlisi gelen Guava kütüphaneleri bir var TreeMultiset
gibi bir çok çalışır ki TreeSet
.
2. ile listenizi sıralayın Collections.sort()
Yukarıda belirtildiği gibi, List
s'nin sınıflandırılması veri yapısının bir manipülasyonudur. Bu nedenle, çeşitli şekillerde sıralanacak olan "gerçeğin bir kaynağına" ihtiyaç duyduğunuz durumlar için, manuel olarak sıralamanın yolu budur.
Listenizi java.util.Collections.sort()
yöntemle sıralayabilirsiniz . İşte nasıl bir kod örneği:
List<String> strings = new ArrayList<String>()
strings.add("lol");
strings.add("cat");
Collections.sort(strings);
for (String s : strings) {
System.out.println(s);
}
// Prints out "cat" and "lol"
Karşılaştırıcıları kullanma
Bir net yararı kullanabilir olmasıdır Comparator
içinde sort
yöntemle. Java da bazı uygulamaları sağlar Comparator
gibi Collator
yerel duyarlı sıralama dizeleri için kullanışlıdır. İşte bir örnek:
Collator usCollator = Collator.getInstance(Locale.US);
usCollator.setStrength(Collator.PRIMARY); // ignores casing
Collections.sort(strings, usCollator);
Eşzamanlı ortamlarda sıralama
sort
Toplama örneği manipüle edileceğinden ve bunun yerine değişmez koleksiyonlar kullanmayı düşünmeniz gerektiğinden , yöntemi kullanmanın eşzamanlı ortamlarda kolay olmadığını unutmayın . Bu, Guava'nın Ordering
sınıfta sağladığı bir şeydir ve basit bir tek astarlıdır:
List<string> sorted = Ordering.natural().sortedCopy(strings);
3. ile listenizi sarın java.util.PriorityQueue
Java'da sıralı bir liste olmasa da, muhtemelen sizin için de işe yarayacak sıralı bir kuyruk var. Öyle java.util.PriorityQueue
sınıfı.
Nico Haase yorumlarda buna cevap veren ilgili bir soru ile bağlantı kurdu .
Sıralı bir koleksiyonda büyük olasılıkla dahili veri yapısını değiştirmek istemezsiniz, bu nedenle PriorityQueue Liste arayüzünü uygulamaz (çünkü bu size öğelerine doğrudan erişim sağlar).
Üzerinde Caveat PriorityQueue
iterasyon
PriorityQueue
Sınıfının uyguladığı Iterable<E>
ve Collection<E>
her zamanki gibi iterated böylece arabirimleri. Ancak, yineleyicinin öğeleri sıralı olarak döndüreceği garanti edilmez. Bunun yerine (Alderath'ın yorumlarda belirttiği gibi) poll()
boşalana kadar kuyruğa ihtiyacınız var .
Herhangi bir koleksiyonu alan yapıcı aracılığıyla bir listeyi öncelik sırasına dönüştürebileceğinizi unutmayın :
List<String> strings = new ArrayList<String>()
strings.add("lol");
strings.add("cat");
PriorityQueue<String> sortedStrings = new PriorityQueue(strings);
while(!sortedStrings.isEmpty()) {
System.out.println(sortedStrings.poll());
}
// Prints out "cat" and "lol"
4. Kendi SortedList
sınıfınızı yazın
NOT: Bunu yapmak zorunda değilsiniz.
Her yeni öğe eklediğinizde sıralanan kendi List sınıfınızı yazabilirsiniz. Bu, uygulamanıza bağlı olarak hesaplamayı ağırlaştırabilir ve iki ana nedenden dolayı bunu bir egzersiz olarak yapmak istemiyorsanız anlamsızdır :
- Yöntemler, öğenin kullanıcının belirttiği dizinde bulunmasını sağlaması gerektiğinden ,
List<E>
arabirimin sahip olduğu sözleşmeyi ihlal eder add
.
- Neden tekerleği yeniden icat ettiniz? Yukarıdaki ilk noktada belirtildiği gibi TreeSet veya Multisets kullanmalısınız.
Ancak, bunu bir alıştırma olarak yapmak istiyorsanız, başlamak için bir kod örneği, AbstractList
soyut sınıfı kullanır :
public class SortedList<E> extends AbstractList<E> {
private ArrayList<E> internalList = new ArrayList<E>();
// Note that add(E e) in AbstractList is calling this one
@Override
public void add(int position, E e) {
internalList.add(e);
Collections.sort(internalList, null);
}
@Override
public E get(int i) {
return internalList.get(i);
}
@Override
public int size() {
return internalList.size();
}
}
İhtiyacınız olan yöntemleri geçersiz kılmadıysanız, gelen varsayılan uygulamaların AbstractList
atacağını unutmayın UnsupportedOperationException
.