Di Jawa ada SortedSet
dan SortedMap
antarmuka. Keduanya termasuk dalam kerangka Java Collections dan menyediakan cara yang diurutkan untuk mengakses elemen.
Namun, dalam pemahaman saya tidak ada SortedList
di Jawa. Anda dapat menggunakannya java.util.Collections.sort()
untuk mengurutkan daftar.
Adakah yang tahu mengapa itu dirancang seperti itu?
java
sorting
collections
Jijoy
sumber
sumber
int diff = this.score - that.score;
return (diff == 0) ? 1 : diff;
Karena ini adalah hack yang bau, saya akan memberikan ini sebagai argumen konstruktor anonim daripada memiliki implementasi Sebanding.Jawaban:
Daftar iterators menjamin pertama dan terutama bahwa Anda mendapatkan elemen daftar dalam urutan internal daftar (alias urutan penyisipan ). Lebih khusus itu dalam urutan Anda memasukkan elemen atau tentang bagaimana Anda memanipulasi daftar. Penyortiran dapat dilihat sebagai manipulasi struktur data, dan ada beberapa cara untuk menyortir daftar.
Saya akan memesan cara-cara dalam urutan kegunaan seperti yang saya pribadi melihatnya:
1. Pertimbangkan untuk menggunakan
Set
atauBag
koleksi sebagai gantinyaCATATAN: Saya menempatkan opsi ini di bagian atas karena ini adalah apa yang biasanya ingin Anda lakukan.
Kumpulan yang diurutkan secara otomatis mengurutkan koleksi pada saat penyisipan , yang berarti ia melakukan penyortiran saat Anda menambahkan elemen ke dalam koleksi. Ini juga berarti Anda tidak perlu mengurutkannya secara manual.
Selain itu, jika Anda yakin tidak perlu khawatir tentang (atau memiliki) elemen duplikat, Anda bisa menggunakannya
TreeSet<T>
. Itu mengimplementasikanSortedSet
danNavigableSet
antarmuka dan bekerja seperti yang mungkin Anda harapkan dari daftar:Jika Anda tidak ingin pemesanan alami, Anda dapat menggunakan parameter konstruktor yang mengambil a
Comparator<T>
.Atau, Anda dapat menggunakan Multiset (juga dikenal sebagai Tas ) , yaitu
Set
yang memungkinkan elemen duplikat, dan ada implementasi pihak ketiga. Terutama dari perpustakaan Jambu adaTreeMultiset
, yang bekerja sangat miripTreeSet
.2. Urutkan daftar Anda dengan
Collections.sort()
Seperti disebutkan di atas, pengurutan
List
s adalah manipulasi struktur data. Jadi untuk situasi di mana Anda membutuhkan "satu sumber kebenaran" yang akan diurutkan dalam berbagai cara, maka mengurutkannya secara manual adalah cara yang harus ditempuh.Anda dapat mengurutkan daftar Anda dengan
java.util.Collections.sort()
metode ini. Berikut ini contoh kode tentang caranya:Menggunakan pembanding
Salah satu manfaat yang jelas adalah bahwa Anda dapat menggunakan
Comparator
dalamsort
metode. Java juga menyediakan beberapa implementasi untukComparator
sepertiCollator
yang berguna untuk lokal string penyortiran sensitif. Ini salah satu contohnya:Menyortir dalam lingkungan berbarengan
Namun perlu dicatat bahwa menggunakan
sort
metode ini tidak ramah di lingkungan bersamaan, karena instance koleksi akan dimanipulasi, dan Anda sebaiknya mempertimbangkan untuk menggunakan koleksi yang tidak dapat diubah. Ini adalah sesuatu yang disediakan oleh Guava diOrdering
kelas dan merupakan one-liner sederhana:3. Bungkus daftar Anda dengan
java.util.PriorityQueue
Meskipun tidak ada daftar yang diurutkan di Jawa, namun ada antrian yang diurutkan yang mungkin akan bekerja dengan baik untuk Anda. Itu
java.util.PriorityQueue
kelasnya.Nico Haase menautkan di komentar ke pertanyaan terkait yang juga menjawab ini.
Dalam koleksi yang diurutkan Anda kemungkinan besar tidak ingin memanipulasi struktur data internal yang mengapa PriorityQueue tidak mengimplementasikan antarmuka Daftar (karena itu akan memberi Anda akses langsung ke elemen-elemennya).
Peringatan pada
PriorityQueue
iteratorThe
PriorityQueue
kelas alat yangIterable<E>
danCollection<E>
antarmuka sehingga dapat mengulangi seperti biasa. Namun, iterator tidak dijamin untuk mengembalikan elemen dalam urutan yang diurutkan. Alih-alih (seperti yang ditunjukkan Alderath dalam komentar), Anda haruspoll()
mengantri sampai kosong.Perhatikan bahwa Anda dapat mengonversi daftar ke antrian prioritas melalui konstruktor yang mengambil koleksi apa pun :
4. Tulis
SortedList
kelas Anda sendiriCATATAN: Anda tidak harus melakukan ini.
Anda bisa menulis kelas Daftar Anda sendiri yang mengurutkan setiap kali Anda menambahkan elemen baru. Ini bisa menjadi perhitungan yang berat tergantung pada implementasi Anda dan tidak ada gunanya , kecuali jika Anda ingin melakukannya sebagai latihan, karena dua alasan utama:
List<E>
dimiliki antarmuka karenaadd
metode harus memastikan bahwa elemen akan berada dalam indeks yang ditentukan pengguna.Namun, jika Anda ingin melakukannya sebagai latihan di sini adalah contoh kode untuk Anda mulai, menggunakan
AbstractList
kelas abstrak:Perhatikan bahwa jika Anda belum mengganti metode yang Anda butuhkan, maka implementasi default dari
AbstractList
akan membuangUnsupportedOperationException
.sumber
Integer maxVal = prioQueue.peek(prioQueue.size() - 1);
. Kedua jika Anda berniat menggunakan PriorityQueue hanya sebagai daftar yang diurutkan, itu akan terdengar kurang intuitif untuk dilihatPriorityQueue
dalam kode daripada seharusnyaSortedList
, jika struktur data seperti itu ada.Collections.sort()
bahkan memungkinkan Anda menentukan fungsi bandingkan yang digunakan untuk mengurutkan, dengan menggunakanComparator
objek.Karena konsep Daftar tidak sesuai dengan konsep koleksi yang diurutkan secara otomatis. Inti dari Daftar adalah bahwa setelah memanggil
list.add(7, elem)
, panggilan kelist.get(7)
akan kembalielem
. Dengan daftar yang diurutkan secara otomatis, elemen dapat berakhir pada posisi yang sewenang-wenang.sumber
Karena semua daftar sudah "diurutkan" berdasarkan urutan item yang ditambahkan (pemesanan FIFO), Anda dapat "resor" dengan urutan lain, termasuk pemesanan elemen secara alami, menggunakan
java.util.Collections.sort()
.EDIT:
Daftar sebagai struktur data didasarkan pada apa yang menarik adalah urutan di mana barang-barang dimasukkan.
Set tidak memiliki informasi itu.
Jika Anda ingin memesan dengan menambahkan waktu, gunakan
List
. Jika Anda ingin memesan dengan kriteria lain, gunakanSortedSet
.sumber
Set dan Map adalah struktur data non-linear. Daftar adalah struktur data linier.
Struktur data pohon
SortedSet
danSortedMap
antarmuka mengimplementasikanTreeSet
danTreeMap
masing-masing menggunakan algoritma implementasi pohon Merah-Hitam yang digunakan. Jadi itu memastikan bahwa tidak ada item duplikat (atau kunci jikaMap
)List
sudah mempertahankan koleksi tertata dan struktur data berbasis indeks, pohon bukanlah struktur data berbasis indeks.Tree
menurut definisi tidak boleh mengandung duplikat.List
kita dapat memiliki duplikat, jadi tidak adaTreeList
(yaitu tidakSortedList
).java.util.Collections.sort()
. Ini mengurutkan daftar yang ditentukan ke dalam urutan menaik, sesuai dengan urutan alami unsur-unsurnya.sumber
JavaFX
SortedList
Meskipun butuh beberapa saat, Java 8 memang memiliki diurutkan
List
. http://docs.oracle.com/javase/8/javafx/api/javafx/collections/transformation/SortedList.htmlSeperti yang Anda lihat di javadocs, itu adalah bagian dari koleksi JavaFX , dimaksudkan untuk memberikan tampilan yang diurutkan pada ObservableList.
Pembaruan: Perhatikan bahwa dengan Java 11, toolkit JavaFX telah pindah ke luar JDK dan sekarang menjadi perpustakaan yang terpisah. JavaFX 11 tersedia sebagai SDK yang dapat diunduh atau dari MavenCentral. Lihat https://openjfx.io
sumber
Untuk setiap pendatang baru, per April 2015, Android sekarang memiliki kelas SortedList di perpustakaan dukungan, yang dirancang khusus untuk bekerja dengannya
RecyclerView
. Inilah posting blog tentang itu.sumber
Poin lainnya adalah kompleksitas waktu operasi penyisipan. Untuk memasukkan daftar, orang mengharapkan kompleksitas O (1). Tetapi ini tidak dapat dijamin dengan daftar yang diurutkan.
Dan poin yang paling penting adalah bahwa daftar tidak berasumsi tentang elemen mereka. Misalnya, Anda dapat membuat daftar hal-hal yang tidak diterapkan
equals
ataucompare
.sumber
SortedSet
hal yang tidak diterapkanComparable
. Lihat konstruktor TreeSet ini .List
antarmuka Java tidak menjamin spesifikasi kinerja pada metodenya.Pikirkan seperti ini:
List
antarmuka memiliki metode sepertiadd(int index, E element)
,set(int index, E element)
. Kontraknya adalah bahwa sekali Anda menambahkan elemen pada posisi X Anda akan menemukannya di sana kecuali Anda menambahkan atau menghapus elemen sebelumnya.Jika implementasi daftar apa pun akan menyimpan elemen dalam urutan selain berdasarkan indeks, metode daftar di atas tidak masuk akal.
sumber
Baris pertama dalam API Daftar mengatakan itu adalah koleksi yang dipesan (juga dikenal sebagai urutan). Jika Anda mengurutkan daftar, Anda tidak dapat mempertahankan pesanan, jadi tidak ada TreeList di Jawa.
Seperti kata API, Daftar Java terinspirasi dari Sequence dan lihat properti sequence http://en.wikipedia.org/wiki/Sequence_(mathematics )
Itu tidak berarti bahwa Anda tidak dapat mengurutkan daftar, tetapi Java ketat dengan definisinya dan tidak menyediakan versi daftar yang diurutkan secara default.
sumber
Jika Anda mencari cara untuk mengurutkan elemen, tetapi juga dapat mengaksesnya dengan indeks secara efisien, Anda dapat melakukan hal berikut:
ArrayList
)Kemudian untuk menambah atau menghapus elemen yang bisa Anda gunakan
Collections.binarySearch
untuk mendapatkan indeks penyisipan / penghapusan. Karena daftar Anda menerapkan akses acak, Anda dapat secara efisien mengubah daftar dengan indeks yang ditentukan.Contoh:
sumber
Pertimbangkan untuk menggunakan indeks-pohon-peta . Ini TreeSet JDK yang disempurnakan yang menyediakan akses ke elemen dengan indeks dan menemukan indeks elemen tanpa iterasi atau daftar tersembunyi yang mendasari yang mendukung pohon. Algoritma ini didasarkan pada pembaruan bobot dari perubahan node setiap kali ada perubahan.
sumber