Saya memiliki berbagai objek person (int age; String name;)
.
Bagaimana saya bisa mengurutkan susunan ini menurut abjad berdasarkan nama dan kemudian berdasarkan usia?
Algoritma mana yang akan Anda gunakan untuk ini?
Anda dapat menggunakan Collections.sort
sebagai berikut:
private static void order(List<Person> persons) {
Collections.sort(persons, new Comparator() {
public int compare(Object o1, Object o2) {
String x1 = ((Person) o1).getName();
String x2 = ((Person) o2).getName();
int sComp = x1.compareTo(x2);
if (sComp != 0) {
return sComp;
}
Integer x1 = ((Person) o1).getAge();
Integer x2 = ((Person) o2).getAge();
return x1.compareTo(x2);
}});
}
List<Persons>
sekarang disortir berdasarkan nama, kemudian berdasarkan usia.
String.compareTo
"Membandingkan dua string secara leksikografis" - dari dokumen .
Collections.sort
adalah metode statis di pustaka Koleksi asli. Itu melakukan penyortiran yang sebenarnya, Anda hanya perlu menyediakan Komparator yang mendefinisikan bagaimana dua elemen dalam daftar Anda harus dibandingkan: ini dicapai dengan menyediakan implementasi compare
metode Anda sendiri .
Comparator
agar tidak harus memasukkan input.Comparable
. Lihat jawabannya oleh @ berry120Comparator<Person> comparator = Comparator.comparing(Person::getName).thenComparingInt(Person::getAge);
Bagi mereka yang dapat menggunakan Java 8 streaming API, ada pendekatan yang lebih rapi yang didokumentasikan dengan baik di sini: Lambdas dan pengurutan
Saya mencari yang setara dengan C # LINQ:
Saya menemukan mekanisme di Java 8 di Comparator:
Jadi di sini adalah cuplikan yang menunjukkan algoritme.
Lihatlah tautan di atas untuk cara yang lebih rapi dan penjelasan tentang bagaimana inferensi tipe Java membuatnya sedikit lebih kikuk untuk didefinisikan dibandingkan dengan LINQ.
Berikut ini adalah unit test lengkap untuk referensi:
sumber
Comparator<Person> comparator = Comparator.comparing(Person::getName).thenComparing(Person::getAge);
thenComparingInt
untuk usia (int)Collections.sort(people, comparator);
saja?Menggunakan pendekatan Java 8 Streams ...
Dan pendekatan Java 8 Lambda ...
Akhirnya...
sumber
Anda perlu menerapkan sendiri
Comparator
, dan kemudian menggunakannya: misalnyaPembanding Anda dapat terlihat sedikit seperti ini:
Pembanding pertama-tama membandingkan nama-nama itu, jika mereka tidak sama dengan itu mengembalikan hasil dari membandingkan mereka, kalau tidak mengembalikan hasil membandingkan ketika membandingkan usia kedua orang.
Kode ini hanya konsep: karena kelasnya tidak berubah Anda bisa memikirkan membangun singleton, bukannya membuat contoh baru untuk setiap penyortiran.
sumber
Anda dapat menggunakan pendekatan Java 8 Lambda untuk mencapai ini. Seperti ini:
sumber
Mintalah kelas orang Anda menerapkan
Comparable<Person>
dan kemudian menerapkan metode compareTo, misalnya:Yang pertama akan mengurutkan berdasarkan nama (huruf besar-kecil) dan kemudian berdasarkan usia. Anda kemudian dapat menjalankan
Arrays.sort()
atauCollections.sort()
pada koleksi atau larik objek Person.sumber
Jambu biji
ComparisonChain
menyediakan cara yang bersih untuk melakukannya. Lihat tautan ini .Utilitas untuk melakukan pernyataan perbandingan berantai. Sebagai contoh:
sumber
Anda bisa melakukan ini:
sumber
Gunakan
Comparator
lalu letakkan benda keCollection
dalamnyaCollections.sort();
sumber
Buat sebanyak mungkin pembanding. Setelah itu, panggil metode "thenComparing" untuk setiap kategori pesanan. Ini adalah cara yang dilakukan oleh Streams. Lihat:
Lihat: Urutkan objek yang ditentukan pengguna pada beberapa bidang - Pembanding (lambda stream)
sumber
Saya akan berhati-hati ketika menggunakan Guava
ComparisonChain
karena itu membuat instance per elemen telah dibandingkan sehingga Anda akan melihat penciptaanN x Log N
rantai perbandingan hanya untuk membandingkan jika Anda menyortir, atauN
contoh jika Anda mengulangi dan memeriksa kesetaraan.Saya lebih suka membuat statis
Comparator
menggunakan Java 8 API terbaru jika memungkinkan atauOrdering
API Guava yang memungkinkan Anda untuk melakukan itu, berikut adalah contoh dengan Java 8:Berikut ini cara menggunakan
Ordering
API Guava : https://github.com/google/guava/wiki/OrderingExplainedsumber
compare
metode tidak membuat apa-apa, tetapi mengembalikan salah satu contoh tunggalLESS
,GREATER
atauACTIVE
tergantung pada hasil perbandingan. Ini adalah pendekatan yang sangat dioptimalkan dan tidak menambah memori atau overhead kinerja.Atau Anda dapat mengeksploitasi fakta bahwa
Collections.sort()
(atauArrays.sort()
) stabil (tidak menyusun ulang elemen yang sama) dan menggunakan aComparator
untuk mengurutkan berdasarkan usia terlebih dahulu dan kemudian yang lain untuk mengurutkan berdasarkan nama.Dalam kasus khusus ini, ini bukan ide yang sangat bagus tetapi jika Anda harus dapat mengubah urutan sortir dalam runtime, ini mungkin berguna.
sumber
Anda dapat menggunakan Pembanding serial generik untuk mengurutkan koleksi berdasarkan beberapa bidang.
sumber
Versi terbaru:
sumber
Untuk kelas
Book
seperti ini:menyortir kelas utama dengan benda tiruan
sumber
Saya tidak yakin apakah jelek untuk menulis kompartor di dalam kelas Person dalam kasus ini. Apakah itu seperti ini:
sumber