Kapan kelas harus Sebanding dan / atau Pembanding?

138

Saya telah melihat kelas yang mengimplementasikan Comparable dan Comparator . Apa artinya ini? Mengapa saya menggunakan yang satu di atas yang lain?

Nick Heiner
sumber
18
Sudahkah Anda membaca javadoc pada mereka? Ini menggambarkan perbedaan dengan cukup jelas.
skaffman
1
Apa yang sebanding dan pembanding dan kapan harus menggunakan pembanding dan pembanding. Untuk mengetahuinya baca tautan ini. ini akan membantu Anda memahami perilaku dan penggunaannya. http://iandjava.blogspot.in/2012/10/comparable-and-comparator.html
RockStar
6
Ini adalah pertanyaan yang bagus dengan jawaban objektif yang baik. Saya kecewa karena ditutup.
Russell Silva
3
Pertanyaan lain tentang StackOverflow menyebut ini sebagai pertanyaan "Apa perbedaan antara pembanding dan pembanding" yang pasti. Mengapa itu ditandai sebagai "tidak konstruktif"? Sebagai Java Newbie, ini adalah pertanyaan yang sangat berguna!
Pete

Jawaban:

241

Teks di bawah ini berasal dari Pembanding vs Sebanding

Sebanding

Objek yang sebanding mampu membandingkan dirinya dengan objek lain. Kelas itu sendiri harus mengimplementasikan java.lang.Comparableantarmuka agar dapat membandingkan instansnya.

Pembanding

Objek pembanding mampu membandingkan dua objek yang berbeda. Kelas tidak membandingkan instance-nya, tetapi beberapa instance kelas lain. Kelas pembanding ini harus mengimplementasikan java.util.Comparatorantarmuka.

Dan
sumber
untuk penjelasan terperinci tentang penggunaan Comparator dan perbandingan: sysdotoutdotprint.com/index.php/2017/03/28/…
mel3kings
2
Artikel bagus lainnya: codecramp.com/java-comparable-vs-comparator
EMM
@ mel3kings - Tautan tidak lagi dapat diakses.
Gaurav
152

Menerapkan Comparableberarti " Saya dapat membandingkan diri saya dengan objek lain. " Ini biasanya berguna ketika ada satu perbandingan standar alami.

Menerapkan Comparatorberarti " Saya dapat membandingkan dua objek lainnya. " Ini biasanya berguna ketika ada beberapa cara membandingkan dua contoh jenis - misalnya Anda dapat membandingkan orang berdasarkan usia, nama dll.

Jon Skeet
sumber
1
Halo skeet, dapatkah Anda meninggalkan kode menggunakan komparator dan komparator.
Mdhar9e
5
@ mdhar9e: Ada banyak contoh di sekitar - jika Anda kesulitan menerjemahkannya ke dalam skenario spesifik Anda, tolong beri lebih banyak informasi dalam pertanyaan baru.
Jon Skeet
2
@alireza: Saya sudah memberikan contoh di paragraf kedua: dengan memiliki pembanding yang berbeda, Anda bisa mengurutkan koleksi yang sama (orang) berdasarkan properti yang berbeda (usia, nama dll). Anda tidak dapat melakukan itu hanya dengan membuat Personimplement Comparable, karena Anda tidak dapat mengubah bagaimana dua orang dibandingkan.
Jon Skeet
1
@feelgoodandprogramming: Tidak, itu adalah algoritma pengurutan yang berbeda . Ada tiga kode yang berpotensi di sini, dalam tiga kelas yang berbeda: 1) Entitas itu sendiri, misalnya Person. 2) Komparator, misalnya PersonAgeComparatoryang dapat membandingkan dua entitas yang berbeda dan memutuskan mana yang harus didahulukan dalam urutan semacam itu. 3) Kode sortir, yang mengambil koleksi entitas dan pembanding, dan mengurutkan koleksi menggunakan pembanding untuk menentukan urutan.
Jon Skeet
2
@RishiKeshPathak: Ya, lebih baik Anda menggunakan Sebanding jika hanya ada satu hal yang jelas untuk dibandingkan. Dan bahkan kemudian Anda bisa menulis Komparator. Jika Anda memiliki dua program berbeda yang menggunakan kelas yang sama, dan satu ingin mengurutkan berdasarkan usia saja dan yang lain dengan nama saja, setidaknya salah satu dari mereka akan perlu menggunakan Pembanding.
Jon Skeet
38

Sebanding memungkinkan kelas mengimplementasikan perbandingannya sendiri:

  • itu di kelas yang sama (sering kali merupakan keuntungan)
  • bisa ada hanya satu implementasi (sehingga Anda tidak dapat menggunakan bahwa jika Anda ingin dua kasus yang berbeda)

Sebagai perbandingan, pembanding adalah perbandingan eksternal:

  • biasanya dalam contoh unik (baik di kelas yang sama atau di tempat lain)
  • Anda menyebutkan setiap implementasi dengan cara yang Anda inginkan untuk menyortir sesuatu
  • Anda dapat menyediakan pembanding untuk kelas yang tidak Anda kontrol
  • implementasi dapat digunakan bahkan jika objek pertama adalah null

Di kedua implementasi, Anda masih dapat memilih untuk apa yang ingin Anda bandingkan . Dengan obat generik, Anda dapat mendeklarasikannya, dan memeriksanya pada waktu kompilasi. Ini meningkatkan keamanan, tetapi juga merupakan tantangan untuk menentukan nilai yang sesuai.

Sebagai panduan, saya biasanya menggunakan kelas atau antarmuka paling umum yang dapat dibandingkan objek itu, dalam semua kasus penggunaan yang saya bayangkan ... Definisi yang tidak terlalu tepat! :-(

  • Comparable<Object>memungkinkan Anda menggunakannya dalam semua kode pada waktu kompilasi (yang baik jika diperlukan, atau buruk jika tidak dan Anda kehilangan kesalahan waktu kompilasi); implementasi Anda harus mengatasi objek, dan dilemparkan sesuai kebutuhan tetapi dengan cara yang kuat.
  • Comparable<Itself> sangat ketat sebaliknya.

Lucu, ketika Anda mensubclass Itself ke Subclass, Subclass juga harus sebanding dan kuat tentang hal itu (atau itu akan melanggar Prinsip Liskov, dan memberi Anda kesalahan runtime).

KLE
sumber
20

java.lang.Comparable

  1. Untuk mengimplementasikan Comparableantarmuka, kelas harus menerapkan metode tunggalcompareTo()

    int a.compareTo(b)

  2. Anda harus memodifikasi kelas yang instansinya ingin Anda urutkan. Sehingga hanya satu urutan urutan yang bisa dibuat per kelas.

java.util.Comparator

  1. Untuk mengimplementasikan antarmuka Comparator, kelas harus menerapkan metode tunggal compare()

    int compare (a,b)

  2. Anda membangun kelas yang terpisah dari kelas yang instansinya ingin Anda urutkan. Sehingga beberapa urutan urutan dapat dibuat per kelas.
codiacTushki
sumber
14

Comparable adalah untuk menyediakan pemesanan default pada objek data, misalnya jika objek data memiliki urutan alami.

A Comparatormewakili pemesanan itu sendiri untuk penggunaan tertentu.

starblue
sumber
8

Comparablebiasanya lebih disukai. Tetapi kadang-kadang kelas sudah mengimplementasikan Comparable, tetapi Anda ingin mengurutkan pada properti yang berbeda. Maka Anda terpaksa menggunakan Comparator.

Beberapa kelas sebenarnya menyediakan Comparatorskasus umum; misalnya, Strings secara case-sensitive secara default ketika diurutkan, tetapi ada juga yang Comparatordisebut statis CASE_INSENSITIVE_ORDER.

Michael Myers
sumber
7
Saya tidak yakin saya setuju dengan Sebanding disukai. Beberapa objek memiliki rasa kuat akan tatanan alam — yaitu angka, dalam semua bentuknya: bilangan alami, bilangan real, tanggal, dll. Tetapi bahkan objek lain yang relatif primitif seperti string karakter tidak memiliki tatanan yang berlaku secara universal. Dalam kasus objek yang lebih kompleks seperti entitas dari model domain aplikasi, mengimplementasikan Comparable biasanya merupakan kesalahan. Banyaknya properti membuat terlalu sulit untuk mengantisipasi urutan apa yang paling diinginkan.
erickson
6

berikut adalah beberapa perbedaan antara Pembanding dan Sebanding yang saya temukan di web:

  1. Jika Anda melihat perbedaan logis antara keduanya adalah Comparator di Java membandingkan dua objek yang diberikan kepadanya, sedangkan antarmuka yang sebanding membandingkan referensi "ini" dengan objek yang ditentukan.

  2. Sebanding dengan Jawa digunakan untuk menerapkan pemesanan objek secara alami. Di Java API String, kelas Date dan wrapper mengimplementasikan antarmuka Sebanding.

  3. Jika ada kelas yang mengimplementasikan antarmuka Sebanding di Jawa maka koleksi objek itu baik Daftar atau Array dapat diurutkan secara otomatis dengan menggunakan metode Collections.sort () atau Array.sort () dan objek akan disortir berdasarkan urutan alami yang ditentukan oleh metode CompareTo.

  4. Objek yang mengimplementasikan Comparable in Java dapat digunakan sebagai kunci dalam peta yang diurutkan atau elemen dalam set yang diurutkan misalnya TreeSet, tanpa menentukan pembanding apa pun.

site: Bagaimana cara menggunakan Comparator dan Comparable di Java? Dengan contoh

Baca selengkapnya: Bagaimana cara menggunakan Comparator dan Comparable di Java? Dengan contoh

kasih sayang
sumber
5

Comparableadalah untuk objek dengan pemesanan alami. Objek itu sendiri tahu bagaimana harus dipesan.
Comparatoradalah untuk objek tanpa pemesanan alami atau ketika Anda ingin menggunakan pemesanan yang berbeda.

Michael Lloyd Lee mlk
sumber
4

Perbedaan antara pembanding dan antarmuka yang sebanding

Comparable digunakan untuk membandingkan dirinya sendiri dengan menggunakan dengan objek lain.

Comparator digunakan untuk membandingkan dua tipe data objek.

SravaniChowdary.Gorijavolu
sumber
2

Jika Anda melihat maka perbedaan logis antara keduanya Comparatordi Jawa membandingkan dua objek yang diberikan kepadanya, sementara Comparableantarmuka membandingkan referensi "ini" dengan objek yang ditentukan.

Comparabledi Jawa digunakan untuk mengimplementasikan pemesanan objek secara alami. Di Java API String, Date dan wrapper mengimplementasikan Comparableantarmuka.

Jika ada kelas yang mengimplementasikan Comparableantarmuka di Jawa maka koleksi objek itu baik Listatau Arraydapat diurutkan secara otomatis dengan menggunakan Collections.sort()atau Array.sort()metode dan objek akan diurutkan berdasarkan urutan alami yang ditentukan oleh compareTometode.

Objek yang mengimplementasikan Comparabledi Jawa dapat digunakan sebagai kunci dalam peta yang diurutkan atau elemen dalam set yang diurutkan misalnya TreeSet, tanpa menentukan apa pun Comparator.

Srinivas
sumber
0

Lib anotasi saya untuk mengimplementasikan Comparable and Comparator:

public class Person implements Comparable<Person> {         
    private String firstName;  
    private String lastName;         
    private int age;         
    private char gentle;         

    @Override         
    @CompaProperties({ @CompaProperty(property = "lastName"),              
        @CompaProperty(property = "age",  order = Order.DSC) })           
    public int compareTo(Person person) {                 
        return Compamatic.doComparasion(this, person);         
    }  
} 

Klik tautan untuk melihat lebih banyak contoh. compamatic

Jianmin Liu
sumber
3
Selamat datang di stackoverflow. Pertanyaan ini sudah lama dan sudah dijawab. Biasanya, yang terbaik adalah tidak menghidupkan kembali utas basi kecuali jika respons Anda menyumbangkan sesuatu yang secara signifikan baru atau berbeda dari jawaban sebelumnya.
oers