Jawaban:
Ini datang sangat terlambat, tetapi ada kelas di JDK hanya untuk tujuan memiliki daftar yang diurutkan. Namanya (agak tidak sesuai dengan Sorted*
antarmuka lainnya ) " java.util.PriorityQueue
". Itu dapat mengurutkan Comparable<?>
atau menggunakan Comparator
.
Perbedaannya dengan List
penggunaan yang diurutkan Collections.sort(...)
adalah bahwa ini akan mempertahankan urutan parsial setiap saat, dengan kinerja penyisipan O (log (n)), dengan menggunakan struktur data tumpukan, sedangkan memasukkan dalam urutan ArrayList
akan menjadi O (n) (yaitu, menggunakan pencarian biner dan pindah).
Namun, tidak seperti a List
, PriorityQueue
tidak mendukung akses yang diindeks ( get(5)
), satu-satunya cara untuk mengakses item di heap adalah dengan mengeluarkannya, satu per satu (dengan demikian namanya PriorityQueue
).
TreeMap dan TreeSet akan memberi Anda iterasi atas konten dalam urutan diurutkan. Atau Anda bisa menggunakan ArrayList dan menggunakan Collections.sort () untuk mengurutkannya. Semua kelas itu ada di java.util
Jika Anda ingin mempertahankan daftar yang disortir yang akan sering Anda ubah (yaitu struktur yang, selain disortir, memungkinkan duplikat dan yang unsur-unsurnya dapat direferensikan secara efisien berdasarkan indeks), kemudian gunakan ArrayList tetapi ketika Anda perlu memasukkan elemen. , selalu gunakan Collections.binarySearch () untuk menentukan indeks tempat Anda menambahkan elemen yang diberikan. Metode yang terakhir memberi tahu Anda indeks yang harus Anda sisipkan agar daftar Anda tetap terurut.
Gunakan kelas TreeMultiset Google Guava . Jambu memiliki API koleksi spektakuler.
Salah satu masalah dengan menyediakan implementasi Daftar yang mempertahankan urutan diurutkan adalah janji yang dibuat dalam JavaDocs dari add()
metode ini.
List
selalu ditambahkan di akhir.
Ada beberapa opsi. Saya menyarankan TreeSet jika Anda tidak ingin duplikat dan objek yang Anda sisipkan sebanding.
Anda juga dapat menggunakan metode statis dari kelas Koleksi untuk melakukan ini.
Lihat Urut Koleksi # (java.util.List) dan TreeSet untuk info lebih lanjut.
Jika Anda hanya ingin mengurutkan daftar, gunakan segala jenis Daftar dan gunakan Collections.sort () . Jika Anda ingin memastikan elemen dalam daftar itu unik dan selalu diurutkan, gunakan SortedSet .
Apa yang saya lakukan adalah mengimplementasikan Daftar yang memiliki instance internal dengan semua metode yang didelegasikan.
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);
}
Setelah itu, saya telah menerapkan metode baru "putOrdered" yang menyisipkan di posisi yang tepat jika elemen tidak ada atau ganti kalau-kalau ada.
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);
}
}
Jika Anda ingin mengizinkan elemen yang berulang ulang, implementasikan saja addOrdered saja (atau keduanya).
public void addOrdered(Contact contact) {
int index=Collections.binarySearch(this.list,contact);
if(index<0){
index= -(index+1);
}
list.add(index, contact);
}
Jika Anda ingin menghindari penyisipan, Anda juga dapat membuang dan tidak mendukung operasi pada metode "tambah" dan "set".
public boolean add(Contact object) {
throw new UnsupportedOperationException("Use putOrdered instead");
}
... dan juga Anda harus berhati-hati dengan metode ListIterator karena mereka dapat mengubah daftar internal Anda. Dalam hal ini Anda dapat mengembalikan salinan daftar internal atau kembali melemparkan pengecualian.
public ListIterator<Contact> listIterator() {
return (new ArrayList<Contact>(list)).listIterator();
}
List
kontrak. Mungkin akan lebih baik hanya menerapkan Collection
. Dan jika ContactList
diurutkan, maka contains()
dapat diimplementasikan menggunakan binarySearch
juga agar lebih efisien.
Cara paling efisien untuk mengimplementasikan daftar yang disortir seperti yang Anda inginkan adalah dengan mengimplementasikan skiplist yang dapat diindeks seperti di sini: Wikipedia: Daftar yang dapat diindeks . Itu akan memungkinkan untuk memasukkan / menghapus dalam O (log (n)) dan akan memungkinkan untuk memiliki akses yang diindeks pada saat yang sama. Dan itu juga akan memungkinkan duplikat.
Skiplist sangat menarik dan, bisa saya katakan, struktur data yang diremehkan. Sayangnya tidak ada implementasi skiplist yang diindeks di perpustakaan berbasis Java, tetapi Anda dapat menggunakan salah satu dari implementasi open source atau mengimplementasikannya sendiri. Ada implementasi Skiplist reguler seperti ConcurrentSkipListSet dan ConcurrentSkipListMap
TreeSet tidak akan berfungsi karena mereka tidak memperbolehkan duplikat plus mereka tidak menyediakan metode untuk mengambil elemen pada posisi tertentu. PriorityQueue tidak akan berfungsi karena tidak memungkinkan mengambil elemen pada posisi tertentu yang merupakan persyaratan dasar untuk daftar. Saya pikir Anda perlu menerapkan algoritma Anda sendiri untuk mempertahankan daftar yang diurutkan di Jawa dengan waktu penyisipan O (logn), kecuali jika Anda tidak memerlukan duplikat. Mungkin solusi bisa menggunakan TreeMap di mana kuncinya adalah subclass dari item yang menimpa metode equals sehingga duplikat diperbolehkan.
Anda dapat mencoba menyelesaikan tugas-tugas ini dengan LambdaJ jika Anda menggunakan versi sebelumnya ke java 8. Anda dapat menemukannya di sini: http://code.google.com/p/lambdaj/
Di sini Anda memiliki contoh:
Urutkan berulang
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());
}
});
Sortir dengan LambdaJ
List<Person> sortedByAgePersons = sort(persons, on(Person.class).getAge());
Tentu saja, memiliki keindahan semacam ini berdampak pada kinerja (rata-rata 2 kali), tetapi dapatkah Anda menemukan kode yang lebih mudah dibaca?
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()))
Masalah dengan PriorityQueue adalah didukung oleh array sederhana, dan logika yang mengatur elemen dilakukan oleh "antrian [2 * n +1]] dan antrian [2 * (n +1)]" thingie. Ini berfungsi dengan baik jika Anda hanya menarik dari kepala, tetapi membuatnya tidak berguna jika Anda mencoba memanggil.
Saya mengatasi masalah ini dengan menggunakan com.google.common.collect.TreeMultimap, tapi saya menyediakan pembanding khusus untuk nilai-nilai, yang dibungkus dengan Pemesanan, yang tidak pernah mengembalikan 0.
ex. untuk Double:
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;
}
}
});
Dengan cara ini saya mendapatkan nilai-nilai secara berurutan ketika saya memanggil .toArray (), dan juga memiliki duplikat.
Yang Anda inginkan adalah pohon pencarian biner. Ia memelihara urutan yang diurutkan sambil menawarkan akses logaritmik untuk pencarian, pemindahan dan penyisipan (kecuali jika Anda memiliki pohon yang mengalami kemunduran - maka itu linear). Ini cukup mudah diimplementasikan dan Anda bahkan dapat membuatnya mengimplementasikan antarmuka Daftar, tetapi kemudian akses indeks menjadi rumit.
Pendekatan kedua adalah memiliki ArrayList dan kemudian implementasi semacam gelembung. Karena Anda memasukkan atau menghapus satu elemen pada suatu waktu, waktu akses untuk penyisipan dan pemindahan adalah linear. Pencarian bersifat logaritmik dan akses indeks konstan (waktu dapat berbeda untuk LinkedList). Satu-satunya kode yang Anda butuhkan adalah 5, mungkin 6 baris semacam gelembung.
Anda dapat menggunakan Arraylist dan Treemap, seperti yang Anda katakan Anda ingin nilai berulang juga maka Anda tidak dapat menggunakan TreeSet, meskipun itu diurutkan juga, tetapi Anda harus mendefinisikan komparator.
Untuk Set Anda dapat menggunakan TreeSet. TreeSet memesan elemen-elemennya berdasarkan pemesanan alami atau urutan penyortiran apa pun yang diteruskan ke Comparable untuk objek tertentu itu. Untuk peta gunakan TreeMap. TreeMap menyediakan kunci penyortiran. Untuk menambahkan objek sebagai kunci ke TreeMap bahwa kelas harus mengimplementasikan antarmuka yang sebanding yang pada gilirannya memaksa untuk menerapkan membandingkan ke () metode yang berisi definisi urutan penyortiran. http://techmastertutorial.in/java-collection-impl.html
Gunakan metode sort () untuk mengurutkan daftar seperti di bawah ini:
List list = new ArrayList();
//add elements to the list
Comparator comparator = new SomeComparator();
Collections.sort(list, comparator);
Untuk referensi, lihat tautan: http://tutorials.jenkov.com/java-collections/sorting.html
Gunakan TreeSet
yang memberi elemen dalam urutan diurutkan. ATAU gunakan Collection.sort()
untuk penyortiran eksternal 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);
}
dengan Java 8 Comparator, jika kita ingin mengurutkan daftar maka Berikut adalah 10 kota terpadat di dunia dan kami ingin mengurutkannya berdasarkan nama, seperti dilansir oleh Time. Osaka, Jepang. ... Kota Meksiko, Meksiko. ... Beijing, Cina. ... São Paulo, Brasil. ... Mumbai, India. ... Shanghai, Cina. ... Delhi, India. ... Tokyo, Jepang.
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);
}
}
Mengurutkan ArrayList sesuai dengan kriteria yang ditentukan pengguna.
Kelas Model
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;
}
}
Kelas Penyortiran
class Sortbyroll implements Comparator<Student>
{
public int compare(Student a, Student b)
{
return a.rollno - b.rollno;
}
}
Kelas Utama
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));
}
}
Keluaran
Unsorted
111 bbbb london
131 aaaa nyc
121 cccc jaipur
Sorted by rollno
111 bbbb london
121 cccc jaipur
131 aaaa nyc