1. Membandingkan objek di Jawa
Di Jawa, objek dapat dibandingkan baik dengan referensi maupun nilai.
Membandingkan referensi
Jika dua variabel menunjuk ke objek yang sama di memori, maka referensi yang disimpan dalam variabel ini adalah sama. Jika Anda membandingkan variabel-variabel ini menggunakan operator persamaan ( ==
), hasilnya benar, dan hasilnya masuk akal. Semuanya sederhana di sini.
Kode | Keluaran konsol |
---|---|
|
|
Membandingkan dengan nilai
Tetapi Anda sering dapat menemukan situasi di mana dua variabel mengacu pada dua objek berbeda yang identik. Misalnya, dua objek string berbeda yang berisi teks yang sama.
Untuk menentukan apakah objek yang berbeda itu identik, gunakan equals()
metode ini. Misalnya:
Kode | Keluaran konsol |
---|---|
|
|
Metode ini equals
tidak terbatas pada String
kelas. Setiap kelas memilikinya.
Bahkan kelas yang Anda tulis sendiri, dan inilah alasannya.
2. Object
kelas
Semua kelas di Jawa mewarisi Object
kelas. Pencipta Java datang dengan pendekatan ini.
Dan jika sebuah kelas mewarisi Object
kelas tersebut, maka ia mendapatkan semua metode Object
kelas tersebut. Dan ini adalah konsekuensi utama dari warisan.
Dengan kata lain, setiap kelas memiliki metode kelas Object
, meskipun kodenya tidak menyebutkannya.
Metode yang diwariskan ini termasuk metode yang terkait dengan perbandingan objek. Ini adalah equals()
dan hashCode()
metode.
Kode | Pada kenyataannya, inilah yang akan kita miliki: |
---|---|
|
|
Pada contoh di atas, kami membuat Person
kelas sederhana dengan parameter nama dan umur, tetapi bukan metode tunggal. Tetapi karena semua kelas mewarisi Object
kelas tersebut, Person
kelas secara otomatis memiliki dua metode:
metode | Keterangan |
---|---|
|
Membandingkan objek saat ini dan objek yang diteruskan |
|
Mengembalikan kode hash dari objek saat ini |
Ternyata benar-benar setiap objek memiliki metodenya equals
, dan objek dari tipe yang berbeda dapat dibandingkan satu sama lain. Kode seperti itu akan dikompilasi dan bekerja dengan sempurna.
Kode | Keluaran konsol |
---|---|
|
|
|
|
3. equals()
metode
Metode equals()
, yang diwarisi dari Object
kelas, mengimplementasikan algoritme paling sederhana untuk membandingkan objek saat ini dengan objek yang diteruskan: metode ini hanya membandingkan referensi ke objek.
Anda mendapatkan hasil yang sama jika Anda hanya membandingkan Person
variabel alih-alih memanggil equals()
metode. Contoh:
Kode | Keluaran konsol |
---|---|
|
|
Ketika equals
metode dipanggil a
, itu hanya membandingkan referensi yang disimpan dalam a
variabel dengan referensi yang disimpan dalam b
variabel.
Namun, perbandingan bekerja secara berbeda untuk String
kelas. Mengapa?
Karena orang-orang yang membuat String
kelas menulis implementasi metode mereka sendiri equals()
.
Implementasi equals()
metode
Sekarang mari kita tulis penerapan metode equals kita sendiri di kelas Person
. Kami akan mempertimbangkan 4 kasus utama.
equals
metode, selalu dibutuhkan Object
objek sebagai argumen
Skenario 1 : objek yang sama di mana equals
metode dipanggil juga diteruskan ke equals
metode. Jika referensi objek saat ini dan objek yang diteruskan sama, metode harus mengembalikan true
. Sebuah objek sama dengan dirinya sendiri.
Dalam kode akan terlihat seperti ini:
Kode | Keterangan |
---|---|
|
Bandingkan referensi |
Skenario 2 : null
diteruskan ke equals
metode — kita tidak punya apa-apa untuk dibandingkan. Objek di mana equals
metode dipanggil pasti bukan nol, jadi kita perlu kembali false
dalam kasus ini.
Dalam kode akan terlihat seperti ini:
Kode | Keterangan |
---|---|
|
Bandingkan referensi Apakah objek yang diteruskan null ? |
Skenario 3 : referensi ke objek yang bukan a Person
diteruskan ke equals
metode. Apakah Person
objek sama dengan bukan Person
objek? Itu adalah pertanyaan bagi pengembang kelas Person
untuk memutuskan sesuai keinginannya.
Tapi biasanya objek harus dari kelas yang sama untuk dianggap sama. Oleh karena itu, jika sesuatu selain objek kelas Person
diteruskan ke metode equals kita, maka kita akan selalu mengembalikan false
. Bagaimana Anda bisa memeriksa jenis objek? Itu benar — dengan menggunakan instanceof
operator.
Inilah tampilan kode baru kita:
Kode | Keterangan |
---|---|
|
Bandingkan referensi Apakah objek yang diteruskan null ? Jika objek yang dilewatkan bukan a Person |
4. Membandingkan dua Person
objek
Apa yang akhirnya kita dapatkan? Jika kita telah mencapai akhir metode, maka kita memiliki Person
referensi objek yang bukan null
. Jadi kami mengonversinya menjadi a Person
dan membandingkan data internal yang relevan dari kedua objek. Dan itu adalah skenario keempat kami .
Kode | Keterangan |
---|---|
|
Bandingkan referensi Apakah objek yang diteruskan null ? Jika objek yang diteruskan bukan Person Typecasting |
Dan bagaimana Anda membandingkan dua Person
objek? Mereka sama jika memiliki nama ( name
) dan umur ( age
) yang sama. Kode terakhir akan terlihat seperti ini:
Kode | Keterangan |
---|---|
|
Bandingkan referensi Apakah objek yang diteruskan null ? Jika objek yang diteruskan bukan Person Typecasting |
Tapi itu belum semuanya.
Pertama, bidang nama adalah a String
, jadi Anda perlu membandingkan bidang nama dengan memanggil equals
metode.
this.name.equals(person.name)
Kedua, name
bidangnya mungkin null
: dalam hal ini, Anda tidak dapat memanggilnya equals
. Anda memerlukan pemeriksaan tambahan untuk null
:
this.name != null && this.name.equals(person.name)
Konon, jika bidang nama ada null
di kedua Person
objek, maka namanya masih sama.
Kode untuk skenario keempat mungkin terlihat seperti ini:
|
Jika usia tidak sama, langsung return false Jika this.name sama dengan null , tidak ada gunanya membandingkan menggunakan equals metode ini. Di sini bidang kedua name sama dengan null , atau tidak. Bandingkan dua bidang nama menggunakan equals metode. |
5. hashCode()
metode
Selain equals
metode yang dimaksudkan untuk melakukan perbandingan mendetail dari semua bidang kedua objek, ada metode lain yang dapat digunakan untuk perbandingan yang tidak tepat tetapi sangat cepat: hashCode()
.
Bayangkan Anda mengurutkan daftar ribuan kata berdasarkan abjad, dan Anda perlu membandingkan pasangan kata berulang kali. Dan kata-katanya panjang, terdiri dari banyak huruf. Secara umum, perbandingan seperti itu akan memakan waktu yang sangat lama.
Tapi itu bisa dipercepat. Misalkan kita memiliki kata-kata yang dimulai dengan huruf yang berbeda — segera jelas bahwa kata-kata itu berbeda. Tetapi jika dimulai dengan huruf yang sama, maka kita belum bisa mengatakan apa hasilnya nanti: kata-katanya bisa sama atau berbeda.
Metode ini hashCode()
bekerja dengan menggunakan prinsip yang serupa. Jika Anda memanggilnya pada suatu objek, itu mengembalikan beberapa angka - analog dengan huruf pertama dalam sebuah kata. Nomor ini memiliki sifat-sifat berikut:
- Objek identik selalu memiliki kode hash yang sama
- Objek yang berbeda dapat memiliki kode hash yang sama, atau kode hashnya dapat berbeda
- Jika objek memiliki kode hash yang berbeda, maka objek tersebut pasti berbeda
Untuk membuatnya lebih jelas, mari kita membingkai ulang properti ini dalam bentuk kata-kata:
- Kata yang identik selalu memiliki huruf pertama yang sama.
- Kata yang berbeda bisa memiliki huruf pertama yang sama, atau huruf pertamanya bisa berbeda
- Jika kata memiliki huruf pertama yang berbeda, maka kata tersebut pasti berbeda
Properti terakhir digunakan untuk mempercepat perbandingan objek:
Pertama, kode hash dari kedua objek dihitung. Jika kode hash ini berbeda, maka objeknya pasti berbeda, dan tidak perlu membandingkannya lebih jauh.
Tetapi jika kode hashnya sama, maka kita masih harus membandingkan objek menggunakan metode yang sama.
6. Kontrak dalam kode
Perilaku yang dijelaskan di atas harus diterapkan oleh semua kelas di Jawa. Selama kompilasi, tidak ada cara untuk memeriksa apakah objek dibandingkan dengan benar.
Pemrogram Java memiliki kesepakatan universal bahwa jika mereka menulis implementasi metode equals() mereka sendiri dan dengan demikian mengesampingkan implementasi standar (di kelas Object
), mereka juga harus menulis implementasi metode mereka sendiri hashCode()
sedemikian rupa sehingga aturan yang disebutkan di atas adalah puas.
Pengaturan ini disebut kontrak .
Jika Anda hanya menerapkan equals()
atau hanya hashCode()
metode di kelas Anda, maka Anda melanggar kontrak (Anda telah melanggar perjanjian). Jangan lakukan ini.
Jika pemrogram lain menggunakan kode Anda, itu mungkin tidak berfungsi dengan benar. Terlebih lagi, Anda akan menggunakan kode yang bergantung pada kepatuhan terhadap kontrak di atas.
Saat mencari elemen, semua koleksi Java terlebih dahulu membandingkan kode hash objek, dan baru kemudian melakukan perbandingan menggunakan equals
metode tersebut.
Itu berarti bahwa jika Anda memberikan metode pada kelas Anda sendiri equals
tetapi Anda tidak menulis hashCode()
metode Anda sendiri atau Anda menerapkannya secara tidak benar, koleksi mungkin tidak berfungsi dengan benar dengan objek Anda.
Misalnya, Anda mungkin menambahkan objek ke daftar lalu mencarinya menggunakan metode contains()
, tetapi koleksi mungkin tidak menemukan objek Anda.
GO TO FULL VERSION