Metode sama dalam kelas objek digunakan untuk mendeteksi apakah suatu objek sama dengan objek lain. Di kelas objek, metode ini menentukan apakah dua objek memiliki referensi yang sama. Jika kedua objek memiliki referensi yang sama, mereka harus sama. Dari sudut pandang ini, masuk akal untuk menggunakannya sebagai operasi default. Namun, untuk sebagian besar kelas, penilaian ini tidak ada artinya. Misalnya, benar -benar tidak ada artinya untuk membandingkan apakah dua printstreams sama dengan cara ini. Namun, seringkali perlu untuk mendeteksi kesetaraan keadaan dua objek. Jika keadaan kedua objek itu sama, kedua objek dianggap sama. Oleh karena itu, secara umum, sama dengan perbandingan harus ditulis ulang di kelas khusus.
Berikut adalah beberapa saran untuk menulis metode Equals () yang sempurna:
(1) Parameter eksplisit bernama OtherObject, dan perlu dikonversi menjadi variabel yang disebut lain nanti
(2) Mendeteksi apakah ini dan OtherObject merujuk ke objek yang sama:
if (this == OtherObject) Return true;
Pernyataan ini hanyalah sebuah optimasi. Bahkan, ini adalah bentuk yang sering diadopsi. Karena menghitung persamaan ini jauh lebih murah daripada membandingkan bidang di kelas satu per satu.
(3) Periksa apakah OtherObject adalah nol, dan jika nol, kembalikan salah. Tes ini diperlukan.
if (OtherObject == null) Return false;
(4) Bandingkan apakah ini dan OtherObject termasuk kelas yang sama. Jika semantik sama dengan perubahan di setiap subkelas, gunakan getClass () untuk mendeteksinya, yang menganggap dirinya sebagai kelas target
if (getClass ()! = OtherObject.getClass ()) Return false;
Jika semua subkelas memiliki semantik yang sama, gunakan instance dari deteksi
if (! (OtherObject instance dari className)) Return false;
(5) Konversi OtherObject ke variabel dari tipe yang sesuai:
ClassName Other = (className) OtherObject;
(6) Sekarang mulai membandingkan semua domain yang perlu dibandingkan. Gunakan == untuk membandingkan domain tipe dasar, dan gunakan sama untuk membandingkan domain objek. Kembalikan true jika semua bidang cocok, jika tidak mengembalikan False;
return field1 == lainnya
Jika Equals didefinisikan ulang dalam subkelas, Anda harus menyertakan panggilan super.Equals (lainnya). Jika deteksi gagal, tidak mungkin menjadi sama. Jika domain dalam superclass sama, bandingkan domain instance di subkelas.
Untuk bidang tipe array, Anda dapat menggunakan metode array statis. Metode yang sama untuk mendeteksi apakah elemen yang sesuai sama.
Mari kita lihat beberapa contoh perbandingan string:
String a = "ABC"; String b = "ABC"; String c = string baru ("ABC"); String d = string baru ("ABC"); System.out.println (a == b); // Benar karena konstanta string dibagikan di Java, hanya ada satu salinan System.out.println (a == C); // false A dan C milik 2 objek yang berbeda System.out.println (A.Equals (c)); // Benar karena metode yang sama dari objek string membandingkan nilai -nilai dalam objek, ia mengembalikan true. (Berbeda dari metode Equals Object) System.out.println (C == D); // Salah Meskipun nilai -nilai dalam objek adalah sama, mereka milik 2 objek yang berbeda, sehingga mereka tidak sama System.out.println (C.Equals (D)); // BENARSederhananya, ketika membandingkan konstanta string, itu sama dengan hasil yang dikembalikan oleh setara. Saat Anda ingin membandingkan nilai objek string, gunakan Equals.
Lihat contoh menggunakan Equals:
Paket Bab05.Equalstest; impor java.util.*; kelas publik equalstest {public static void main (string [] args) {karyawan alice1 = karyawan baru ("Alice Adams", 75000, 1987, 12, 15); Karyawan ALICE2 = ALICE1; // Referensi Objek yang sama karyawan ALICE3 = Karyawan Baru ("Alice Adams", 75000, 1987, 12, 15); Karyawan Bob = karyawan baru ("Bob Brandson", 50000, 1989, 10, 1); System.out.println ("ALICE1 == ALICE2:" + (ALICE1 == ALICE2)); System.out.println ("ALICE1 == ALICE3:" + (ALICE1 == ALICE3)); System.out.println ("Alice1.Equals (ALICE3):" + (ALICE1.Equals (ALICE3)))); System.out.println ("Alice1.Equals (Bob):" + (Alice1.Equals (Bob))); System.out.println (bob.tostring ()); }} kelas karyawan {pegawai publik (string n, double s, int tahun, int bulan, int day) {name = n; Gaji = S; Kalender Gregoriancalendar = Gregoriancalendar baru (tahun, bulan, hari); hireday = calendar.getTime (); } public string getName () {return name; } public double getSalary () {return gaji; } tanggal publik getHireday () {return hireday; } public void raisisalary (double bypercent) {double raise = gaji * bypercent / 100; Gaji += Naikkan; } @Override Public Boolean Equals (Object OtherObject) {// Tes cepat untuk melihat apakah objek diidentifikasi jika (this == OtherObject) Return true; // Harus mengembalikan false jika parameter eksplisit adalah null if (OtherObject == null) return false; // Jika yang digolongkan tidak cocok, mereka tidak dapat sama jika (getClass ()! = OtherObject.getClass ()) Return False; // Sekarang kita tahu OtherObject adalah karyawan non-nol karyawan lain = (karyawan) lainnya; // uji apakah bidang yang mengidentifikasi nilai -nilai pengembalian nama. } @Override public int hashCode () {return 7 * name.HashCode () + 11 * ganda baru (gaji) .hashCode () + 13 * hireday.hashcode (); } @Override Public String ToString () {return getClass (). GetName () + "[name =" + name + ", gaji =" + gaji + ", hireday =" + hireday + "]"; } nama string pribadi; gaji ganda pribadi; kencan pribadi sewa; } Class Manager memperluas karyawan {Manager Public (String n, Double S, int Year, Int Month, int Day) {super (n, s, tahun, bulan, hari); Bouns = 0; } @Override public double getSalary () {double basesalary = super.getSalary (); Return Basesalary + Bouns; } public void setBouns (double b) {bouns = b; } @Override public boolean setara (objek OtherObject) {if (! Super.equals (OtherObject)) return false; Manajer Lainnya = (Manajer) OtherObject; // super sama memeriksa bahwa ini dan lainnya milik bouns return kelas yang sama == Other.bouns; } @Override public int hashCode () {return super.hashcode () + 17 * double baru (bouns) .hashCode (); } @Override public string toString () {return super.toString () + "[bouns =" + bouns + "]"; } bouns double pribadi; } Masuk lebih dalam dan bagilah menjadi 2 kategori sesuai dengan "apakah kelas menimpa metode Equals ()".
(1) Jika suatu kelas tidak mengganti metode Equals (), ketika membandingkan dua objek melalui Equals (), itu sebenarnya membandingkan apakah kedua objek tersebut adalah objek yang sama. Pada saat ini, setara dengan membandingkan kedua objek ini dengan "==".
(2) Kita dapat mengganti metode Equals () dari kelas untuk membiarkan Equals () membandingkan apakah dua objek sama dengan cara lain. Praktik yang biasa adalah: jika isi dua objek sama, metode Equals () mengembalikan true; Kalau tidak, ia mengembalikan Fasle.
Selanjutnya, mari kita beri contoh untuk menjelaskan dua situasi di atas.
1. Kasus "tidak mengesampingkan metode ()"
Kode ini adalah sebagai berikut (equalstest1.java):
Impor java.util.*; impor java.lang.Compparable;/*** @desc equals () Program uji. */kelas publik equalstest1 {public static void main (string [] args) {// membuat 2 objek orang baru dengan konten yang sama, // gunakan sama untuk membandingkan apakah mereka orang yang setara p1 = orang baru ("eee", 100); Orang p2 = orang baru ("eee", 100); System.out.printf ("%s/n", p1.equals (p2)); } /*** @desc class orang. */ orang kelas statis privat {int usia; Nama string; orang publik (nama string, int usia) {this.name = name; this.age = usia; } public string toString () {return name + " -" + usia; }}} Hasil Menjalankan:
Salin kode sebagai berikut: Salah
Analisis Hasil Kami menggunakan P1.Equals (P2) untuk "membandingkan apakah P1 dan P2 sama." Faktanya, metode Equals () objek.java disebut, yaitu, (P1 == P2) disebut. Ini untuk membandingkan "apakah P1 dan P2 adalah objek yang sama".
Dari definisi P1 dan P2, kita dapat melihat bahwa meskipun kontennya sama, mereka adalah dua objek yang berbeda! Oleh karena itu, hasil pengembalian salah.
2. Situasi "Metode overwriting Equals ()"
Kami memodifikasi equalstest1.java di atas: angkanya metode Equals ().
Kode ini adalah sebagai berikut (equalstest2.java):
Impor java.util.*; impor java.lang.Compparable;/*** @desc equals () Program uji. */kelas publik equalstest2 {public static void main (string [] args) {// membuat 2 objek orang baru dengan konten yang sama, // gunakan sama untuk membandingkan apakah mereka orang yang setara p1 = orang baru ("eee", 100); Orang p2 = orang baru ("eee", 100); System.out.printf ("%s/n", p1.equals (p2)); } /*** @desc class orang. */ orang kelas statis privat {int usia; Nama string; orang publik (nama string, int usia) {this.name = name; this.age = usia; } public string toString () {return name + " -" + usia; } / *** @desc override equals metode* / @Override public boolean sama (objek obj) {if (obj == null) {return false; } // Jika itu adalah objek yang sama, kembalikan true, jika tidak, kembalikan False if (this == obj) {return true; } // menilai apakah jenisnya sama jika (this.getClass ()! = Obj.getClass ()) {return false; } Orang orang = (orang) obj; return name.equals (person.name) && usia == person.age; }}} Hasil Menjalankan:
Salin kode sebagai berikut: Benar
Analisis Hasil:
Kami mengesampingkan fungsi Equals () orang di Equalstest2.java: Ketika nama dan usia dari kedua orang itu sama, ia mengembalikan true.
Oleh karena itu, hasil lari kembali benar.
Setelah mengatakan itu, mari kita bicara tentang persyaratan Java untuk Equals (). Ada poin berikut:
Simetri: Jika x.equals (y) mengembalikan "true", maka y.equals (x) juga harus mengembalikan "true".
Reflektivitas: X.Equals (x) harus mengembalikan "true".
Analogi: jika x.equals (y) mengembalikan "true", dan y.equals (z) mengembalikan "true", maka z.equals (x) juga harus mengembalikan "true".
Konsistensi: Jika X.Equals (y) mengembalikan "Benar", selama konten X dan Y tetap tidak berubah, tidak peduli berapa kali Anda mengulangi X.Equals (y), pengembaliannya akan "benar".
Non-kosong, x.equals (null), selalu mengembalikan "false"; X.Equals (objek dari berbagai jenis dan x) selalu mengembalikan "false".
Sekarang, mari kita tinjau peran Equals (): Tentukan apakah dua objek sama. Ketika kami menulis ulang Equals (), tidak mungkin untuk mengubah fungsinya!
Apa perbedaan antara Equals () dan ==?
==: Fungsinya adalah untuk menentukan apakah alamat dua objek sama. Artinya, tentukan apakah kedua objek tersebut adalah objek yang sama.
Equals (): Fungsinya adalah untuk menentukan apakah dua objek sama. Namun, umumnya memiliki dua kondisi penggunaan (telah dijelaskan secara rinci di Bagian 1 sebelumnya):
Kasus 1, kelas tidak mengganti metode Equals (). Kemudian ketika membandingkan dua objek kelas ini melalui Equals (), itu setara dengan membandingkan dua objek ini dengan "==".
Kasus 2, kelas menimpa metode Equals (). Secara umum, kami mengganti metode Equals () untuk membuat konten dua objek sama; Jika isinya sama, itu mengembalikan true (yaitu, kedua objek dianggap sama).
Di bawah ini, bandingkan perbedaannya dengan contoh.
Kodenya adalah sebagai berikut:
Impor java.util.*; impor java.lang.Compparable;/*** @desc equals () Program uji. */kelas publik equalstest3 {public static void main (string [] args) {// membuat 2 objek orang baru dengan konten yang sama, // gunakan sama untuk membandingkan apakah mereka orang yang sama p1 = orang baru ("eee", 100); Orang p2 = orang baru ("eee", 100); System.out.printf ("P1.Equals (P2): %S/N", P1.Equals (P2)); System.out.printf ("P1 == P2: %S/N", P1 == P2); } /*** @desc class orang. */ orang kelas statis privat {int usia; Nama string; orang publik (nama string, int usia) {this.name = name; this.age = usia; } public string toString () {return name + " -" + usia; } / *** @desc override equals metode* / @Override public boolean sama (objek obj) {if (obj == null) {return false; } // Jika itu adalah objek yang sama, kembalikan true, jika tidak, kembalikan False if (this == obj) {return true; } // menilai apakah jenisnya sama jika (this.getClass ()! = Obj.getClass ()) {return false; } Orang orang = (orang) obj; return name.equals (person.name) && usia == person.age; }}} Hasil Menjalankan:
p1.Equals (p2): truep1 == p2: false
Analisis Hasil:
Di equalstest3.java:
(1) P1.Equals (P2)
Ini untuk menentukan apakah isi P1 dan P2 sama. Karena orang mengesampingkan metode Equals (), dan setara ini () digunakan untuk menentukan apakah isi P1 dan P2 sama, persis isi P1 dan P2 sama; Karena itu, kembalikan benar.
(2) P1 == P2
Ini untuk menentukan apakah P1 dan P2 adalah objek yang sama. Karena mereka masing -masing adalah dua objek orang baru; Oleh karena itu, kembalikan salah.