Saya ingin tahu mengapa .compareTo()
ada di Comparable
antarmuka sementara metode seperti .equals
di Object
kelas. Bagi saya, tampaknya sewenang-wenang mengapa metode seperti .compareTo()
belum ada di Object
kelas.
Untuk menggunakan .compareTo()
, Anda mengimplementasikan Comparable
antarmuka dan mengimplementasikan .compareTo()
metode untuk tujuan Anda. Untuk .equals()
metode, Anda cukup mengganti metode di kelas Anda, karena semua kelas mewarisi dari Object
kelas.
Pertanyaan saya adalah mengapa metode seperti .compareTo()
di antarmuka yang Anda implementasikan daripada di kelas seperti Object
? Demikian juga, mengapa .equals()
metode di kelas Object
dan bukan di beberapa antarmuka yang harus diimplementasikan?
java
language-design
interfaces
Wesley
sumber
sumber
Eq
typeclass).Jawaban:
Tidak semua objek dapat dibandingkan, tetapi semua objek dapat diperiksa untuk kesetaraan. Jika tidak ada yang lain, seseorang dapat melihat apakah dua objek ada di lokasi yang sama dalam memori (referensi kesetaraan).
Apa artinya
compareTo()
duaThread
benda? Bagaimana satu utas "lebih besar dari" yang lain? Bagaimana Anda membandingkan duaArrayList<T>
s?The
Object
kontrak berlaku untuk semua kelas Java. Jika bahkan satu kelas tidak dapat dibandingkan dengan contoh lain dari kelasnya sendiri, makaObject
tidak dapat mengharuskannya untuk menjadi bagian dari antarmuka.Joshua Bloch menggunakan kata-kata kunci "pemesanan alami" ketika menjelaskan mengapa kelas mungkin ingin diterapkan
Comparable
. Tidak setiap kelas memiliki urutan alami seperti yang saya sebutkan dalam contoh saya di atas, jadi tidak setiap kelas harus menerapkanComparable
atauObject
memilikicompareTo
metode.Java Efektif, Edisi Kedua : Joshua Bloch. Butir 12, Halaman 62. Elips menghapus referensi ke bab lain dan contoh kode.
Untuk kasus di mana Anda tidak ingin memaksakan sebuah memesan pada non
Comparable
kelas yang tidak memiliki memesan alami, Anda selalu dapat menyediakanComparator
contoh untuk bantuan semacam itu.sumber
==
untuk yang terakhir, ini memiliki cincin kosong untuk itu. Mengabaikan standar redundan, orang dapat menemukan alasan yang sah untuk tidak menganggapequals
semua kelas, karena tidak semua tipe dapat mendukung relasi ekivalensi.==
" karena bagaimana kelas-kelas tersebut dipakai adalah detail implementasi tetapi bahasa membuatnya mustahil untuk disembunyikan. Anda bisa mengatakan bahwa siapa pun yang membandingkan duaInteger
s dengan referensi adalah idiot, tetapi membiarkan perbandingan untuk memulai adalah masih bodoh.The JLS §4.3.2 mendefinisikan
class
objek dengan cara berikut:Jadi, itu sebabnya
equals
ada diObject
tetapicompareTo
dalam antarmuka yang terpisah. Saya berspekulasi bahwa mereka ingin tetapObject
seminimal mungkin. Mereka mungkin mengira bahwa hampir semuaObjects
akan perluequals
danhashCode
(yang sebenarnya hanyalah bentuk pengujian kesetaraan) tetapi tidak semua objek perlu memiliki konsep pemesanan , yangcompareTo
digunakan untuk apa.sumber
Equitable<T>
tetapi jikaObject
diimplementasikan, maka setiap kelas akan menjadiEquitable<Object>
. Pada titik itu, apakah ada perbedaan? Efeknya tidak juga, dalam kompleksitas ya.object
memilikiEquals(object)
, seperti di Jawa, tetapi ada jugaIEquatable<T>
antarmuka. Meskipun alasan utama keberadaannya adalah untuk menghindari tinju ketikaT
adalah tipe nilai, yang tidak mungkin di Jawa.equals
dinyatakanObject
secara langsung:The methods equals and hashCode are declared for the benefit of hashtables such as java.util.Hashtable (§21.7)
- karena desain Java kompatibel dengan mundur, pilihan desain Java 1.0 adalah alasan sebenarnya untukequals
keberadaannya.Selain jawaban Snowman yang sangat baik, ingatlah bahwa
Comparable
itu telah menjadi antarmuka umum untuk waktu yang lama. Tipe tidak diimplementasikancompareTo(object)
, ia mengimplementasikan dicompareTo(T)
manaT
jenisnya sendiri. Ini tidak dapat diimplementasikan padaobject
, karenaobject
tidak tahu kelas yang akan diturunkan darinya.object
bisa mendefinisikan suatucompareTo(object)
metode, tetapi ini akan memungkinkan bukan hanya apa yang Snowman tunjukkan, perbandingan antara duaArrayList<T>
s atau antara duaThread
s, tetapi bahkan perbandingan antara aArrayList<T>
dan aThread
. Itu bahkan lebih tidak masuk akal.sumber
Misalkan saya memiliki dua referensi objek: X mengidentifikasi contoh
String
memegang konten "George"; Y mengidentifikasi contohPoint
memegang koordinat [12,34]. Pertimbangkan dua pertanyaan berikut:Apakah X dan Y mengidentifikasi objek yang setara?
Haruskah X mengurutkan sebelum, sesudah, atau setara dengan Y?
Fakta bahwa X dan Y mengidentifikasi contoh tipe yang tidak terkait tidak menimbulkan masalah ketika mempertimbangkan pertanyaan pertama. Objek hanya dapat dianggap setara jika tipenya memiliki basis umum yang mendefinisikannya setara; sejak
String
danPoint
tidak memiliki basis seperti itu (satu-satunya jenis basis umum mereka menganggap semua objek yang berbeda sebagai tidak setara) jawabannya hanyalah "tidak".Namun, fakta bahwa tipe-tipe itu tidak berhubungan, menimbulkan masalah besar terkait dengan pertanyaan kedua. Beberapa jenis mendefinisikan hubungan pemesanan di antara instans mereka, dan beberapa relasi pemesanan bahkan meluas ke beberapa tipe [mis. Akan mungkin untuk
BigInteger
danBigDecimal
untuk menentukan metode perbandingan yang akan memungkinkan instance dari kedua tipe untuk diurutkan relatif terhadap instance yang lain], tetapi tidak mungkin secara umum untuk mengambil dua contoh arbitrer dan bertanya "Haruskah X mengurutkan sebelum, setelah, atau setara dengan Y" dan mendapatkan total pemesanan. Mungkin saja untuk bertanya "Haruskah X menyortir sebelum, sesudah, setara, atau tidak dibuka sehubungan dengan Y" jika objek diminta untuk melaporkan pemesanan yang konsisten meskipun tidak totalsatu, tetapi sebagian besar algoritma pengurutan membutuhkan pemesanan total. Jadi, bahkan jika semua objek dapat mengimplementasikancompareTo
metode jika "unranked" adalah pengembalian yang valid, metode seperti itu tidak akan cukup berguna untuk membenarkan keberadaannya.sumber