Yanıtlar:
Bu çok geç geliyor, ancak JDK'da sıralı bir listeye sahip olmak için bir sınıf var. Adı "(diğer Sorted*
arayüzlerle biraz bozuk )" java.util.PriorityQueue
". Comparable<?>
S veya a kullanarak sıralama yapabilir Comparator
.
List
Sıralanmış bir kullanma ile fark Collections.sort(...)
, bunun bir yığın veri yapısı kullanarak O (log (n)) ekleme performansı ile her zaman kısmi bir düzen sürdürmesidir, oysa sıralanmış bir ekleme ArrayList
O (n) (yani, ikili arama ve taşıma kullanarak).
Ancak, a'nın aksine List
, PriorityQueue
dizine alınan erişimi ( get(5)
) desteklemez , bir öbekteki öğelere erişmenin tek yolu bunları teker teker çıkarmaktır (dolayısıyla ad PriorityQueue
).
TreeMap ve TreeSet, içerikler üzerinde sıralanmış bir sırayla yineleme sağlar. Veya bir ArrayList kullanabilir ve sıralamak için Collections.sort () yöntemini kullanabilirsiniz. Tüm bu sınıflar java.util'de
Bir korumak istiyorsanız sıralı liste , olur sık değiştirmek , daha sonra bir ArrayList kullanmak ancak (sıralanmakta olan ek olarak, izin verir, yani bir yapıya bunun elemanları verimli endeksi ile başvurulabilir çiftleri ve) ne zaman bir öğe eklemek için gerekmez , belirli bir öğeyi eklediğiniz dizini belirlemek için her zaman Collections.binarySearch () öğesini kullanın. İkinci yöntem, listenizi sıralı olarak tutmak için eklemeniz gereken dizini belirtir.
Google Guava'nın TreeMultiset sınıfını kullanın . Guava'nın muhteşem bir koleksiyon API'sı var.
Listenin sıralamayı koruyan bir uygulamasının sağlanmasındaki bir sorun, add()
yöntemin JavaDoc'larında verilen vaattir .
List
Sonunda bir her zaman eklenmesi gerekliliğinden bahsettiğiniz için +1 .
Birkaç seçenek var. Yinelenen istemiyorsanız ve eklediğiniz nesneler karşılaştırılabilirse TreeSet'i öneririm.
Bunu yapmak için Collections sınıfının statik yöntemlerini de kullanabilirsiniz.
Daha fazla bilgi için bkz. Collections # sort (java.util.List) ve TreeSet .
Sadece bir liste sıralamak isterseniz, her türlü kullanımı Listesi ve kullanımı () Collections.sort . Listedeki öğelerin benzersiz ve her zaman sıralandığından emin olmak istiyorsanız bir SortedSet kullanın .
Yaptığım tüm yöntemler ile dahili bir örneği olan uygulamak List olduğunu.
public class ContactList implements List<Contact>, Serializable {
private static final long serialVersionUID = -1862666454644475565L;
private final List<Contact> list;
public ContactList() {
super();
this.list = new ArrayList<Contact>();
}
public ContactList(List<Contact> list) {
super();
//copy and order list
List<Contact>aux= new ArrayList(list);
Collections.sort(aux);
this.list = aux;
}
public void clear() {
list.clear();
}
public boolean contains(Object object) {
return list.contains(object);
}
Sonra, yeni bir yöntem "putOrdered" uyguladım, eğer öğe yoksa ya da mevcut olması durumunda değiştirilirse uygun pozisyonda yerleştirilir.
public void putOrdered(Contact contact) {
int index=Collections.binarySearch(this.list,contact);
if(index<0){
index= -(index+1);
list.add(index, contact);
}else{
list.set(index, contact);
}
}
Tekrarlanan öğelere izin vermek istiyorsanız, bunun yerine addOrdered öğesini (veya her ikisini birden) uygulayın.
public void addOrdered(Contact contact) {
int index=Collections.binarySearch(this.list,contact);
if(index<0){
index= -(index+1);
}
list.add(index, contact);
}
Ekleme işlemlerinden kaçınmak isterseniz, "ekleme" ve "ayarlama" yöntemlerine de atma ve desteklenmeyen işlem özel durumu atabilirsiniz.
public boolean add(Contact object) {
throw new UnsupportedOperationException("Use putOrdered instead");
}
... ve ayrıca dahili listenizi değiştirebilecekleri için ListIterator yöntemlerine dikkat etmelisiniz. Bu durumda dahili listenin bir kopyasını döndürebilir veya tekrar bir istisna atabilirsiniz.
public ListIterator<Contact> listIterator() {
return (new ArrayList<Contact>(list)).listIterator();
}
List
sözleşmeyi ihlal etmesidir . Belki sadece uygulamak daha iyi olur Collection
. Ve ContactList
sıralanırsa, daha verimli olmak için de contains()
kullanılarak uygulanabilir binarySearch
.
İstediğiniz gibi sıralı bir listeyi uygulamanın en etkili yolu, aşağıdaki gibi dizine eklenebilir bir listeyi uygulamak olacaktır: Wikipedia: Dizine eklenebilir listeyi atlamak . O (log (n)) içinde ekleme / çıkarma yapılmasına izin verir ve aynı zamanda dizin oluşturulmuş erişime izin verir. Ayrıca kopyalara da izin verir.
Atla listesi oldukça ilginç ve diyebilirim ki, hafife alınmış veri yapısı. Ne yazık ki Java temel kitaplığında dizinli bir atlama listesi uygulaması yoktur, ancak açık kaynak uygulamalarından birini kullanabilir veya kendiniz uygulayabilirsiniz. ConcurrentSkipListSet ve ConcurrentSkipListMap gibi düzenli Skiplist uygulamaları vardır
TreeSet, yinelemelere izin vermedikleri ve öğeyi belirli bir konumda getirme yöntemi sağlamadığı için çalışmaz. PriorityQueue, liste için temel bir gereklilik olan belirli bir konumda öğelerin getirilmesine izin vermediğinden çalışmaz. Yinelenenlere gerek duymadıkça, Java'da O (logn) ekleme süresiyle sıralanmış bir listeyi korumak için kendi algoritmanızı uygulamanız gerektiğini düşünüyorum. Belki bir çözüm, anahtarın eşitleme yöntemini geçersiz kılan öğenin bir alt sınıfı olduğu bir TreeMap kullanıyor olabilir, böylece kopyalara izin verilir.
Java 8'in önceki sürümlerini kullanıyorsanız, bu görevleri LambdaJ ile çözmeyi deneyebilirsiniz. Http://code.google.com/p/lambdaj/
Burada bir örnek var:
Sıralı Yinelemeli
List<Person> sortedByAgePersons = new ArrayList<Person>(persons);
Collections.sort(sortedByAgePersons, new Comparator<Person>() {
public int compare(Person p1, Person p2) {
return Integer.valueOf(p1.getAge()).compareTo(p2.getAge());
}
});
LambdaJ ile sırala
List<Person> sortedByAgePersons = sort(persons, on(Person.class).getAge());
Tabii ki, bu tür bir güzellik performansa (ortalama 2 kez) etki eder, ancak daha okunabilir bir kod bulabilir misiniz?
Collections.sort(persons, (p1, p2) -> p1.getAge().compareTo(p2.getAge()));
//or
persons.sort((p1, p2) -> p1.getAge().compareTo(p2.getAge()));
-(p1.getAge().compareTo(p2.getAge()))
PriorityQueue ile ilgili sorun, basit bir dizi tarafından yedeklenmesidir ve öğeleri sırayla alan mantık, "kuyruk [2 * n + 1] ve kuyruk [2 * (n + 1)]" nesnesi tarafından yapılır. Sadece kafadan çekerseniz harika çalışır, ancak bir noktada .toArray'ı çağırmaya çalışıyorsanız işe yaramaz hale getirir.
Com.google.common.collect.TreeMultimap kullanarak bu sorunu gidermek, ama asla 0 döndüren bir Sipariş, sarılmış değerler için özel bir karşılaştırıcı sağlar.
ex. Çift Kişilik:
private static final Ordering<Double> NoEqualOrder = Ordering.from(new Comparator<Double>() {
@Override
public int compare(Double d1, Double d2)
{
if (d1 < d2) {
return -1;
}
else {
return 1;
}
}
});
Bu şekilde değerleri .toArray () çağırdığımda sırayla alıyorum ve ayrıca yinelemeleri var.
İstediğiniz ikili bir arama ağacı. Arama, kaldırma ve eklemeler için logaritmik erişim sunarken sıralı düzeni korur (yozlaşmış bir ağacınız yoksa, o zaman doğrusaldır). Uygulamak oldukça kolaydır ve hatta List arabirimini uygulamasını sağlayabilirsiniz, ancak daha sonra dizin erişimi karmaşıklaşır.
İkinci yaklaşım, bir ArrayList ve sonra bir kabarcık sıralama uygulamasına sahip olmaktır. Bir kerede bir öğe eklediğiniz veya çıkardığınız için, ekleme ve kaldırma işlemlerinin erişim süreleri doğrusaldır. Aramalar logaritmik ve dizin erişim sabitidir (LinkedList için süreler farklı olabilir). İhtiyacınız olan tek kod 5, belki 6 satır kabarcık sıralamadır.
Arraylist ve Treemap'i kullanabilirsiniz, tekrarlanan değerleri istediğinizi de söylediğiniz gibi, TreeSet'i de sıralayabilirsiniz, ancak sıralanmış olsa da, karşılaştırıcı tanımlamanız gerekir.
Set için TreeSet'i kullanabilirsiniz. TreeSet öğelerini doğal bir sıralama veya söz konusu nesne için Karşılaştırılabilir'e aktarılan herhangi bir sıralama düzeni temelinde sıralar. Harita için TreeMap kullanın. TreeMap tuşların üzerinde sıralama sağlar. Bir nesneyi TreeMap'e anahtar olarak eklemek için bu sınıf, sıralama düzeninin tanımını içeren Compare () yöntemini uygulamaya zorlayan karşılaştırılabilir bir arabirim uygulamalıdır. http://techmastertutorial.in/java-collection-impl.html
Listeyi aşağıdaki gibi sıralamak için sort () yöntemini kullanın:
List list = new ArrayList();
//add elements to the list
Comparator comparator = new SomeComparator();
Collections.sort(list, comparator);
Referans için şu bağlantıya bakın: http://tutorials.jenkov.com/java-collections/sorting.html
TreeSet
Öğeleri sıralı olarak veren kullanın . VEYA Collection.sort()
ile harici sıralama için kullanın Comparator()
.
import java.util.TreeSet;
public class Ass3 {
TreeSet<String>str=new TreeSet<String>();
str.add("dog");
str.add("doonkey");
str.add("rat");
str.add("rabbit");
str.add("elephant");
System.out.println(str);
}
Java 8 Karşılaştırıcısı ile, listeyi sıralamak istiyorsak, Dünyanın en kalabalık 10 şehri buradayız ve Time tarafından bildirildiği gibi ada göre sıralamak istiyoruz. Osaka, Japonya. ... Mexico City, Meksika. ... Pekin, Çin. ... São Paulo, Brezilya. ... Mumbai, Hindistan. ... Şangay, Çin. ... Delhi, Hindistan. ... Tokyo, Japonya.
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
public class SortCityList {
/*
* Here are the 10 most populated cities in the world and we want to sort it by
* name, as reported by Time. Osaka, Japan. ... Mexico City, Mexico. ...
* Beijing, China. ... São Paulo, Brazil. ... Mumbai, India. ... Shanghai,
* China. ... Delhi, India. ... Tokyo, Japan.
*/
public static void main(String[] args) {
List<String> cities = Arrays.asList("Osaka", "Mexico City", "São Paulo", "Mumbai", "Shanghai", "Delhi",
"Tokyo");
System.out.println("Before Sorting List is:-");
System.out.println(cities);
System.out.println("--------------------------------");
System.out.println("After Use of List sort(String.CASE_INSENSITIVE_ORDER) & Sorting List is:-");
cities.sort(String.CASE_INSENSITIVE_ORDER);
System.out.println(cities);
System.out.println("--------------------------------");
System.out.println("After Use of List sort(Comparator.naturalOrder()) & Sorting List is:-");
cities.sort(Comparator.naturalOrder());
System.out.println(cities);
}
}
ArrayList'i kullanıcı tanımlı ölçütlere göre sıralama.
Model Sınıfı
class Student
{
int rollno;
String name, address;
public Student(int rollno, String name, String address)
{
this.rollno = rollno;
this.name = name;
this.address = address;
}
public String toString()
{
return this.rollno + " " + this.name + " " + this.address;
}
}
Sınıflandırma Sınıfı
class Sortbyroll implements Comparator<Student>
{
public int compare(Student a, Student b)
{
return a.rollno - b.rollno;
}
}
Ana sınıf
class Main
{
public static void main (String[] args)
{
ArrayList<Student> ar = new ArrayList<Student>();
ar.add(new Student(111, "bbbb", "london"));
ar.add(new Student(131, "aaaa", "nyc"));
ar.add(new Student(121, "cccc", "jaipur"));
System.out.println("Unsorted");
for (int i=0; i<ar.size(); i++)
System.out.println(ar.get(i));
Collections.sort(ar, new Sortbyroll());
System.out.println("\nSorted by rollno");
for (int i=0; i<ar.size(); i++)
System.out.println(ar.get(i));
}
}
Çıktı
Unsorted
111 bbbb london
131 aaaa nyc
121 cccc jaipur
Sorted by rollno
111 bbbb london
121 cccc jaipur
131 aaaa nyc