Apa perbedaan antara bandingkan () dan bandingkanTo ()?


Jawaban:


160

Dari Java Catatan :

  • a.compareTo(b):
    Antarmuka yang dapat dibandingkan : Membandingkan nilai dan mengembalikan int yang memberi tahu jika nilai-nilai dibandingkan kurang dari, sama, atau lebih besar dari.
    Jika objek kelas Anda memiliki tatanan alami , implementasikan Comparable<T>antarmuka dan tentukan metode ini. Semua kelas Java yang memiliki memesan alami menerapkan Comparable<T>- Contoh: String, kelas wrapper ,BigInteger

  • compare(a, b):
    Antarmuka pembanding: Membandingkan nilai dari dua objek. Ini diimplementasikan sebagai bagian dari Comparator<T>antarmuka, dan penggunaan tipikal adalah untuk mendefinisikan satu atau lebih kelas utilitas kecil yang mengimplementasikan ini, untuk meneruskan ke metode seperti sort()atau untuk digunakan dengan mengurutkan struktur data seperti TreeMapdanTreeSet . Anda mungkin ingin membuat objek Comparator untuk berikut ini:

    • Perbandingan ganda . Untuk menyediakan beberapa cara berbeda untuk menyortir sesuatu. Misalnya, Anda mungkin ingin mengurutkan kelas Person berdasarkan nama, ID, usia, tinggi, ... Anda akan menentukan Pembanding untuk masing-masing untuk diteruskan ke sort()metode.
    • Kelas sistem Untuk memberikan metode perbandingan untuk kelas yang tidak dapat Anda kendalikan. Misalnya, Anda dapat menentukan Pembanding untuk String yang membandingkannya berdasarkan panjang.
    • Pola strategi Untuk mengimplementasikan pola Strategi, yaitu situasi di mana Anda ingin merepresentasikan suatu algoritma sebagai objek yang dapat Anda lewati sebagai parameter, simpan dalam struktur data, dll.

Jika objek kelas Anda memiliki satu urutan pengurutan alami, Anda mungkin tidak perlu bandingkan ().


Ringkasan dari http://www.digizol.com/2008/07/java-sorting-comparator-vs-comparable.html

Comparable
Sebuah objek yang sebanding mampu membandingkan dirinya dengan objek lain.

Pembanding
Suatu obyek pembanding mampu membandingkan dua obyek yang berbeda. Kelas tidak membandingkan instance-nya, tetapi beberapa instance kelas lainnya.


Gunakan konteks kasus:

Antarmuka yang sebanding

Metode yang sama dan ==dan != operator menguji persamaan / ketidaksamaan, tetapi tidak menyediakan cara untuk menguji nilai relatif .
Beberapa kelas (misalnya, String dan kelas lain dengan pengurutan alami) mengimplementasikan Comparable<T>antarmuka, yang mendefinisikan compareTo()metode.
Anda akan ingin menerapkan Comparable<T>di kelas Anda jika Anda ingin menggunakannya dengan metode Collections.sort()atau Arrays.sort().

Mendefinisikan sebuah objek Comparator

Anda dapat membuat Pembanding untuk mengurutkan sembarang cara untuk kelas apa pun .
Misalnya, Stringkelas mendefinisikan CASE_INSENSITIVE_ORDERpembanding .


Perbedaan antara kedua pendekatan tersebut dapat dikaitkan dengan gagasan tentang:
Koleksi Berurutan :

Saat Koleksi diurutkan, itu berarti Anda dapat mengulang koleksi dalam urutan tertentu (tidak acak) (a Hashtabletidak diurutkan).

Koleksi dengan tatanan alam tidak sekedar dipesan, tetapi dipilah . Mendefinisikan tatanan alam bisa jadi sulit! (seperti dalam urutan String alami ).


Perbedaan lainnya, ditunjukkan oleh HaveAGuess di komentar :

  • Comparable sedang dalam implementasi dan tidak terlihat dari antarmuka, jadi saat Anda menyortir Anda tidak benar-benar tahu apa yang akan terjadi.
  • Comparator memberi Anda kepastian bahwa pemesanan akan ditentukan dengan baik.

2
Karena jawaban ini lengkap, berikut adalah sesuatu yang mengganggu saya tentang Comparable yang mungkin ingin Anda tambahkan: Ini ada dalam implementasi dan tidak terlihat dari antarmuka, jadi ketika Anda mengurutkan, Anda tidak benar-benar tahu apa yang akan terjadi. Menggunakan pembanding memberi Anda kepastian bahwa pemesanan akan ditentukan dengan baik
HaveAGuess

@HaveAG poin yang bagus. Saya telah memasukkan komentar Anda dalam jawaban untuk visibilitas lebih lanjut.
VonC

benda memiliki tatanan alami, apa arti tatanan alam di sini? Apakah anggota data string misalnya nama di kelas karyawan memiliki urutan alami ??
Narendra Jaggi

@NarendraJaggi Lihat en.wikipedia.org/wiki/Enumeration . Perintah yang memfasilitasi pencacahan. "Alami" dalam arti bahwa pengurutan yang baik pada kumpulan indeks memberikan cara unik untuk membuat daftar elemen berikutnya yang diberi pencacahan sebagian
VonC

2
@VedantKekan Terima kasih. Saya telah memulihkan 2 tautan dalam jawaban ini.
VonC

16

compareTo()berasal dari Comparableantarmuka.

compare()berasal dari Comparatorantarmuka.

Kedua metode melakukan hal yang sama, tetapi setiap antarmuka digunakan dalam konteks yang sedikit berbeda.

The Sebanding antarmuka digunakan untuk memaksakan memesan alami pada objek dari kelas pelaksana. The compareTo()metode ini disebut metode perbandingan alami. The Comparator antarmuka digunakan untuk memaksakan memesan total pada objek dari kelas yang mengimplementasikan. Untuk informasi selengkapnya, lihat tautan untuk mengetahui kapan tepatnya harus menggunakan setiap antarmuka.


dapatkah kamu memberikan beberapa contoh? Kedua metode memberikan jawaban yang sama?

Saya tidak tahu mengapa 'Comparable' untuk pemesanan alami? Kita bisa menyesuaikannya, bukan?
c-an

14

Kemiripan:
Keduanya adalah cara khusus untuk membandingkan dua objek.
Keduanya mengembalikan intgambaran hubungan antara dua objek.

Perbedaan: Metode compare()adalah metode yang wajib Anda terapkan jika Anda mengimplementasikan Comparatorantarmuka. Ini memungkinkan Anda untuk melewatkan dua objek ke dalam metode dan mengembalikan intpenjelasan hubungan mereka.

Comparator comp = new MyComparator();
int result = comp.compare(object1, object2);

Metode compareTo()adalah metode yang wajib Anda terapkan jika Anda mengimplementasikan Comparableantarmuka. Ini memungkinkan sebuah objek untuk dibandingkan dengan objek sejenis.

String s = "hi";
int result = s.compareTo("bye");

Ringkasan:
Pada dasarnya mereka adalah dua cara berbeda untuk membandingkan berbagai hal.


9

Metode tidak harus memberikan jawaban yang sama. Itu tergantung pada objek / kelas mana yang Anda panggil.

Jika Anda mengimplementasikan kelas Anda sendiri yang ingin Anda bandingkan pada tahap tertentu, Anda dapat meminta mereka mengimplementasikan antarmuka Comparable dan mengimplementasikan metode bandingkanTo () yang sesuai.

Jika Anda menggunakan beberapa kelas dari API yang tidak mengimplementasikan antarmuka Comparable, tetapi Anda masih ingin membandingkannya. Yaitu untuk penyortiran. Anda dapat membuat kelas Anda sendiri yang mengimplementasikan antarmuka Comparator dan dalam metode bandingkan () Anda mengimplementasikan logika.


3

Sebanding antarmuka berisi metode yang disebut compareTo(obj)yang mengambil hanya satu argumen dan membandingkan dirinya dengan contoh lain atau objek dari kelas yang sama.

Antarmuka pembanding berisi metode yang disebut compare(obj1,obj2)yang mengambil dua argumen dan membandingkan nilai dua objek dari kelas yang sama atau berbeda.


3
compareTo(T object)

berasal dari antarmuka java.lang.Comparable, diimplementasikan untuk membandingkan objek ini dengan yang lain untuk memberikan nilai int negatif untuk objek ini kurang dari, 0 untuk sama, atau nilai positif lebih besar dari yang lain. Ini adalah metode perbandingan yang lebih nyaman, tetapi harus diterapkan di setiap kelas yang ingin Anda bandingkan.

compare(T obj1, T obj2)

berasal dari antarmuka java.util.Comparator, diimplementasikan dalam kelas terpisah yang membandingkan objek kelas lain untuk memberikan nilai int negatif untuk objek pertama kurang dari, 0 untuk sama dengan, atau nilai positif lebih besar dari objek kedua. Ini diperlukan ketika Anda tidak bisa membuat implementasi kelas bandingkanTo () karena tidak bisa dimodifikasi. Ini juga digunakan saat Anda menginginkan cara berbeda untuk membandingkan objek, tidak hanya satu (seperti berdasarkan nama atau usia).


3

Dengan menggunakan Comparator, kita dapat menuliskan n sejumlah logika perbandingan untuk sebuah kelas .

Misalnya

Untuk Kelas Mobil

Kita dapat memiliki kelas Pembanding untuk dibandingkan berdasarkan nomor model mobil. Kami juga dapat memiliki kelas Pembanding untuk membandingkan berdasarkan tahun model mobil.

Kelas Mobil

public class Car  {

    int modelNo;

    int modelYear;

    public int getModelNo() {
        return modelNo;
    }

    public void setModelNo(int modelNo) {
        this.modelNo = modelNo;
    }

    public int getModelYear() {
        return modelYear;
    }

    public void setModelYear(int modelYear) {
        this.modelYear = modelYear;
    }

}

Pembanding # 1 berdasarkan Model No.

public class CarModelNoCompartor implements Comparator<Car>{

    public int compare(Car o1, Car o2) {

        return o1.getModelNo() - o2.getModelNo();
    }

}

Pembanding # 2 berdasarkan Model Tahun

public class CarModelYearComparator implements Comparator<Car> {

    public int compare(Car o1, Car o2) {

        return o1.getModelYear() - o2.getModelYear();
    }

}

Tetapi ini tidak mungkin dengan kasus antarmuka yang sebanding .

Dalam kasus antarmuka yang dapat dibandingkan, kita hanya dapat memiliki satu logika dalam metode bandingkanTo () .


2

Hubungan objek yang memiliki metode ini dan kolaboratornya berbeda.

compareTo()adalah metode antarmuka Comparable , sehingga digunakan untuk membandingkan instance INI dengan yang lain.

compare()adalah metode Pembanding antarmuka , sehingga digunakan untuk membandingkan dua contoh berbeda dari kelas lain satu sama lain.

Jika Anda mau, mengimplementasikan Comparableberarti bahwa instance kelas dapat dengan mudah dibandingkan.
Menerapkan Comparatorberarti, bahwa instance cocok untuk membandingkan objek yang berbeda (dari kelas lain).


2

Perbedaan utamanya adalah dalam penggunaan antarmuka:

Comparable (yang memiliki bandingkanTo ()) memerlukan objek yang akan dibandingkan (untuk menggunakan TreeMap, atau untuk mengurutkan daftar) untuk mengimplementasikan antarmuka itu. Tetapi bagaimana jika kelas tidak mengimplementasikan Comparable dan Anda tidak dapat mengubahnya karena itu bagian dari pustaka pihak ketiga? Kemudian Anda harus mengimplementasikan Comparator, yang sedikit kurang nyaman digunakan.


2

compareTo()dipanggil pada satu objek, untuk membandingkannya dengan objek lain. compare()dipanggil pada beberapa objek untuk membandingkan dua objek lainnya.

Perbedaannya adalah di mana logika yang melakukan perbandingan aktual didefinisikan.


Bukan apa yang saya sebut sebagai jawaban yang fantastis, tapi menurut saya itu tidak pantas mendapat suara negatif.
Paul Tomblin

Setuju, secara pribadi saya memberikan suara negatif untuk jawaban yang salah atau menyesatkan. Yang ini pasti benar.
Joachim Sauer

Jadi, di mana orang-orang 'ramah' yang tidak menyukai saya? Ini adalah jawaban benar kedua saya yang ditolak karena seseorang melewatkan intinya. Entah poin downvoting atau poin jawaban saya. Hidup ini begitu kejam .. ;-)
Abgan

0

Ketika Anda ingin mengurutkan Daftar yang menyertakan Objek Foo, kelas Foo harus mengimplementasikan antarmuka yang Dapat Dibandingkan, karena metode pengurutan Daftar menggunakan metode ini.

Saat Anda ingin menulis kelas Util yang membandingkan dua kelas lain, Anda dapat mengimplementasikan kelas Comparator.


0


Nama Tabel Karyawan , DoB, Gaji
Tomas, 2/10/1982, 300
Daniel, 3/11/1990, 400
Kwame, 2/10/1998, 520

The Sebanding antarmuka memungkinkan Anda untuk mengurutkan daftar Karyawan benda misalnya dengan mengacu ke salah satu bidang utama - misalnya, Anda bisa mengurutkan berdasarkan nama atau gaji dengan CompareTo () metode

emp1.getName().compareTo(emp2.getName())

Antarmuka yang lebih fleksibel untuk persyaratan tersebut disediakan oleh antarmuka Pembanding , yang satu-satunya metode adalah bandingkan ()

public interface Comparator<Employee> {
 int compare(Employee obj1, Employee obj2);
}

Kode sampel

public class NameComparator implements Comparator<Employee> {

public int compare(Employee e1, Employee e2) {
     // some conditions here
        return e1.getName().compareTo(e2.getName()); // returns 1 since (T)omas > (D)an 
    return e1.getSalary().compareTo(e2.getSalary()); // returns -1 since 400 > 300
}

}


0

Satu hal lagi:

  • compareTo()dari Comparableantarmuka dan compare()dari Comparatorantarmuka.
  • Comparabledigunakan untuk mendefinisikan pengurutan default untuk objek dalam kelas sementara Comparatordigunakan untuk mendefinisikan pengurutan kustom untuk diteruskan ke metode.

0

Ada aspek teknis yang harus ditekankan juga. Katakanlah Anda memerlukan parameterisasi perilaku perbandingan dari kelas klien, dan Anda bertanya-tanya apakah akan menggunakan Comparableatau Comparatoruntuk metode seperti ini:

class Pokemon {
    int healthPoints;
    int attackDamage;
    public void battle (Comparable<Pokemon> comparable, Pokemon opponent) {
        if (comparable.compareTo(opponent) > 0) { //comparable needs to, but cannot, access this.healthPoints for example
            System.out.println("battle won");
        } else {
            System.out.println("battle lost");
        }
    }
}

comparableakan lambda atau objek, dan tidak ada cara untuk comparablemengakses bidang thisPokemon. (Dalam lambda, thismengacu pada contoh kelas luar dalam lingkup lambda, seperti yang didefinisikan dalam teks program.) Jadi ini tidak terbang , dan kita harus menggunakan Comparatordengan dua argumen.


0

Gunakan antarmuka yang Dapat Dibandingkan untuk mengurutkan berdasarkan lebih dari satu nilai seperti usia, nama, nama_dept ... Untuk satu nilai, gunakan antarmuka Pembanding


-2
Important Answar
String name;
int roll;

public int compare(Object obj1,Object obj2) { // For Comparator interface
    return obj1.compareTo(obj1);
}

public int compareTo(Object obj1) { // For Comparable Interface
    return obj1.compareTo(obj);
}

Di sini di pernyataan return obj1.compareTo(obj1)atau return obj1.compareTo(obj)hanya mengambil Objek; primitif tidak diperbolehkan. Sebagai contoh

name.compareTo(obj1.getName()) // Correct Statement.

Tapi

roll.compareTo(obj1.getRoll()) 
// Wrong Statement Compile Time Error Because roll 
// is not an Object Type, it is primitive type.

namanya Objek String jadi itu berhasil. Jika Anda ingin mengurutkan nomor gulungan siswa daripada menggunakan kode di bawah ini.

public int compareTo(Object obj1) { // For Comparable Interface
    Student s = (Student) obj1;
    return rollno - s.getRollno();
}  

atau

public int compare(Object obj1,Object obj2) { // For Comparator interface
    Student s1 = (Student) obj1;
    Student s2 = (Student) obj2;
    return s1.getRollno() - s2.getRollno();
}  
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.