Halo! Hari ini kita akan membicarakan topik yang sangat penting dan menarik yaitu membandingkan objek satu sama lain sama dengan() di Java. Dan memang, dalam kasus apa di Java Objek A akan sama dengan Objek B ? Mari kita coba menulis sebuah contoh:
public class Car {
String model;
int maxSpeed;
public static void main(String[] args) {
Car car1 = new Car();
car1.model = "Ferrari";
car1.maxSpeed = 300;
Car car2 = new Car();
car2.model = "Ferrari";
car2.maxSpeed = 300;
System.out.println(car1 == car2);
}
}
Keluaran konsol:
false
Oke, berhenti. Mengapa sebenarnya kedua mobil ini tidak setara? Kami memberi mereka properti yang sama, tetapi hasil perbandingannya salah. Jawabannya sederhana. Operator ==
tidak membandingkan properti objek, tetapi tautan. Sekalipun dua objek mempunyai 500 properti yang identik, hasil perbandingannya tetap salah. Lagi pula, tautan car1
menunjuk car2
ke dua objek berbeda , ke dua alamat berbeda. Bayangkan sebuah situasi dengan membandingkan orang. Mungkin ada seseorang di dunia ini yang memiliki nama, warna mata, umur, tinggi badan, warna rambut, dll yang sama dengan Anda. Artinya, Anda serupa dalam banyak hal, tetapi Anda tetap bukan saudara kembar, dan terlebih lagi bukan orang yang sama. Operator menerapkan logika yang kurang lebih sama ==
ketika kita menggunakannya untuk membandingkan dua objek. Tetapi bagaimana jika Anda memerlukan logika berbeda dalam program Anda? Misalnya, jika program Anda mensimulasikan analisis DNA. Dia harus membandingkan kode DNA dua orang dan menentukan bahwa mereka kembar.
public class Man {
int dnaCode;
public static void main(String[] args) {
Man man1 = new Man();
man1.dnaCode = 1111222233;
Man man2 = new Man();
man2.dnaCode = 1111222233;
System.out.println(man1 == man2);
}
}
Keluaran konsol:
false
Masuk akal jika hasilnya sama (bagaimanapun juga, kami tidak mengubah apa pun), tetapi sekarang kami tidak puas! Memang dalam kehidupan nyata, analisis DNA adalah jaminan seratus persen bahwa kita menghadapi anak kembar. Namun program dan operator kami ==
mengatakan sebaliknya. Bagaimana kita dapat mengubah perilaku ini dan memastikan bahwa jika tes DNA cocok, program akan memberikan hasil yang benar? Untuk tujuan ini, metode khusus dibuat di Java - sama dengan() .
Metode Equals() di Java
Seperti metodetoString()
yang kita bahas sebelumnya, sama dengan() termasuk dalam kelas, Object
kelas paling penting di Java, tempat semua kelas lainnya diturunkan. Namun, equal() sendiri tidak akan mengubah perilaku program kita dengan cara apa pun:
public class Man {
String dnaCode;
public static void main(String[] args) {
Man man1 = new Man();
man1.dnaCode = "111122223333";
Man man2 = new Man();
man2.dnaCode = "111122223333";
System.out.println(man1.equals(man2));
}
}
Keluaran konsol:
false
Hasilnya sama persis, lalu mengapa cara ini diperlukan? :/ Itu mudah. Faktanya adalah sekarang kami menggunakan metode ini seperti yang diterapkan di kelas itu sendiri Object
. Dan jika kita masuk ke kode kelas Object
dan melihat bagaimana metode ini diterapkan di dalamnya dan apa fungsinya, kita akan melihat:
public boolean equals(Object obj) {
return (this == obj);
}
Inilah alasan mengapa perilaku program kami tidak berubah! Di dalam metode same() kelas Object
terdapat perbandingan referensi yang sama, ==
. Namun trik dari cara ini adalah kita bisa menimpanya. Mengganti berarti menulis metode equal() Anda sendiri di kelas kita Man
dan membuatnya berperilaku sesuai keinginan kita! Sekarang kami tidak puas bahwa cek tersebut man1.equals(man2)
pada dasarnya melakukan hal yang sama seperti man1 == man2
. Inilah yang akan kami lakukan dalam situasi ini:
public class Man {
int dnaCode;
public boolean equals(Man man) {
return this.dnaCode == man.dnaCode;
}
public static void main(String[] args) {
Man man1 = new Man();
man1.dnaCode = 1111222233;
Man man2 = new Man();
man2.dnaCode = 1111222233;
System.out.println(man1.equals(man2));
}
}
Keluaran konsol:
true
Hasil yang sangat berbeda! Dengan menulis metode yang sama dengan() dan bukan metode standar, kita mencapai perilaku yang benar: sekarang jika dua orang memiliki kode DNA yang sama, program akan memberi tahu kita: “Analisis DNA menunjukkan bahwa mereka kembar” dan hasilnya benar! Dengan mengganti metode sama dengan() di kelas Anda, Anda dapat dengan mudah membuat logika perbandingan objek yang diperlukan. Kami telah menyentuh perbandingan objek hanya secara umum. Kami masih akan mengadakan kuliah besar terpisah tentang topik ini (Anda dapat membacanya dengan cepat sekarang, jika Anda tertarik).
Perbandingan string di Java - Perbandingan string
Mengapa kita memperlakukan perbandingan string secara terpisah dari yang lainnya? Faktanya, baris-baris dalam pemrograman adalah cerita yang sangat berbeda. Pertama, jika kita mengambil semua program Java yang ditulis oleh umat manusia, maka sekitar 25% objek di dalamnya terdiri dari program tersebut. Oleh karena itu, topik ini sangat penting. Kedua, proses membandingkan string sangat berbeda dengan objek lainnya. Mari kita lihat contoh sederhana:
public class Main {
public static void main(String[] args) {
String s1 = "JavaRush is the best site to learn Java!";
String s2 = new String("JavaRush is the best site to learn Java!");
System.out.println(s1 == s2);
}
}
Keluaran konsol:
false
Tapi kenapa salah? Barisnya persis sama, kata demi kata :/ Anda dapat berasumsi: ini karena operator ==
membandingkan referensi! Bagaimanapun, s1
mereka s2
memiliki alamat berbeda di memori. Jika pemikiran ini muncul di benak Anda, mari kita ulangi contoh kita:
public class Main {
public static void main(String[] args) {
String s1 = "JavaRush is the best site to learn Java!";
String s2 = "JavaRush is the best site to learn Java!";
System.out.println(s1 == s2);
}
}
Sekarang kami juga memiliki dua tautan, tetapi hasilnya berubah menjadi sebaliknya: Output konsol:
true
Benar-benar bingung? :) Mari kita cari tahu. Operator ==
sebenarnya membandingkan alamat di memori. Aturan ini selalu berhasil dan tidak perlu diragukan lagi. Artinya jika s1 == s2
hasilnya benar, kedua string ini memiliki alamat yang sama di memori. Dan memang benar! Saatnya berkenalan dengan area memori khusus untuk menyimpan string - string pool ( String pool
) String pool adalah area untuk menyimpan semua nilai string yang Anda buat dalam program Anda. Untuk apa itu diciptakan? Seperti disebutkan sebelumnya, string menempati sebagian besar objek. Dalam program besar apa pun, banyak baris yang dibuat. Untuk menghemat memori, inilah yang diperlukan String Pool
- baris dengan teks yang Anda butuhkan ditempatkan di sana, dan di masa depan, tautan yang baru dibuat merujuk ke area memori yang sama, tidak perlu mengalokasikan memori tambahan setiap saat. Setiap kali Anda menulis String = “........”
, program memeriksa apakah ada baris dengan teks seperti itu di kumpulan string. Jika ada, yang baru tidak akan dibuat. Dan tautan baru akan menunjuk ke alamat yang sama di kumpulan string tempat string ini disimpan. Oleh karena itu, ketika kami menulis di program tersebut
String s1 = "JavaRush is the best site to learn Java!";
String s2 = "JavaRush is the best site to learn Java!";
tautannya s2
menunjuk ke tempat yang sama persis dengan s1
. Perintah pertama membuat baris baru di kumpulan string dengan teks yang kita perlukan, dan ketika sampai pada baris kedua, perintah tersebut hanya merujuk ke area memori yang sama dengan s1
. Anda bisa membuat minimal 500 baris lagi dengan teks yang sama, hasilnya tidak akan berubah. Berhenti. Namun mengapa contoh ini tidak berhasil bagi kita sebelumnya?
public class Main {
public static void main(String[] args) {
String s1 = "JavaRush is the best site to learn Java!";
String s2 = new String("JavaRush is the best site to learn Java!");
System.out.println(s1 == s2);
}
}
Menurut saya, secara intuitif Anda sudah bisa menebak apa alasannya :) Coba tebak sebelum membaca lebih lanjut. Anda dapat melihat bahwa kedua garis ini dibuat secara berbeda. Yang pertama dengan bantuan operator new
, dan yang kedua tanpa operator. Inilah alasannya. Operator baru, saat membuat objek, secara paksa mengalokasikan area baru di memori untuk objek tersebut . Dan baris yang dibuat dengan new
, tidak berakhir di String Pool
: ia menjadi objek terpisah, meskipun teksnya sama persis dengan baris yang sama dari String Pool
'a. Yaitu jika kita menulis kode berikut:
public class Main {
public static void main(String[] args) {
String s1 = "JavaRush is the best site to learn Java!";
String s2 = "JavaRush is the best site to learn Java!";
String s3 = new String("JavaRush is the best site to learn Java!");
}
}
Di memori akan terlihat seperti ini: Dan setiap kali objek baru dibuat, new
area baru akan dialokasikan di memori, meskipun teks di dalam baris baru sama! Sepertinya kita sudah memilah operatornya ==
, tapi bagaimana dengan teman baru kita - metode sama dengan()?
public class Main {
public static void main(String[] args) {
String s1 = "JavaRush is the best site to learn Java!";
String s2 = new String("JavaRush is the best site to learn Java!");
System.out.println(s1.equals(s2));
}
}
Keluaran konsol:
true
Menarik. Kami tahu persis apa s1
dan s2
menunjuk ke area berbeda dalam memori. Namun, metode sama dengan () mengatakan bahwa keduanya sama. Mengapa? Ingat, di atas kami mengatakan bahwa metode sama dengan() dapat diganti di kelas Anda sehingga dapat membandingkan objek sesuai kebutuhan Anda? Itulah yang mereka lakukan di kelas String
. Ini memiliki metode sama dengan () yang diganti. Dan itu tidak membandingkan tautan, melainkan urutan karakter dalam string. Dan jika teks dalam string sama, tidak masalah bagaimana teks tersebut dibuat dan di mana disimpan: di kumpulan string, atau di area memori terpisah. Hasil perbandingannya akan benar. Omong-omong, Java memungkinkan Anda membandingkan string dengan benar tanpa membedakan huruf besar-kecil. Dalam situasi normal, jika Anda menulis salah satu baris, misalnya dalam huruf kapital, hasil perbandingannya akan salah:
public class Main {
public static void main(String[] args) {
String s1 = "JavaRush is the best site to learn Java!";
String s2 = new String("JAVARUSH - ЛУЧШИЙ САЙТ ДЛЯ ИЗУЧЕНИЯ JAVA!");
System.out.println(s1.equals(s2));
}
}
Keluaran konsol:
false
Untuk kasus ini, kelas String
memiliki metode equalsIgnoreCase()
. Jika hal utama dalam perbandingan Anda adalah urutan karakter tertentu, dan bukan kasusnya, Anda dapat menggunakannya. Misalnya, ini akan berguna ketika membandingkan dua alamat email:
public class Main {
public static void main(String[] args) {
String address1 = "Moscow, Academician Korolev street, 12";
String address2 = new String("Г. МОСКВА, УЛ. АКАДЕМИКА КОРОЛЕВА, ДОМ 12");
System.out.println(address1.equalsIgnoreCase(address2));
}
}
Dalam hal ini, jelas bahwa kita berbicara tentang alamat yang sama, jadi menggunakan metode ini equalsIgnoreCase()
akan menjadi keputusan yang tepat.
Metode String.intern()
Kelas iniString
memiliki metode rumit lainnya - intern()
; Metode ini intern()
bekerja langsung dengan String Pool
'om. Jika Anda memanggil suatu metode intern()
pada sebuah string, itu:
- Terlihat untuk melihat apakah ada string dengan teks ini di kumpulan string
- Jika ada, kembalikan tautan ke sana di kumpulan
- Jika tidak, ia menempatkan baris dengan teks ini di kumpulan string dan mengembalikan tautan ke sana.
intern()
pada referensi string yang dibuat melalui new, kita dapat membandingkannya dengan referensi string dari String Pool
'a melalui ==
.
public class Main {
public static void main(String[] args) {
String s1 = "JavaRush is the best site to learn Java!";
String s2 = new String("JavaRush is the best site to learn Java!");
System.out.println(s1 == s2.intern());
}
}
Keluaran konsol:
true
Sebelumnya, jika kami membandingkannya tanpa intern()
, hasilnya salah. Sekarang metode tersebut intern()
memeriksa apakah ada baris dengan teks "JavaRush - situs terbaik untuk belajar Java!" di kolam string. Tentu saja itu ada: kami membuatnya saat kami menulis
String s1 = "JavaRush is the best site to learn Java!";
Telah diperiksa bahwa referensi s1
dan referensi yang dikembalikan oleh metode s2.intern()
menunjuk ke area yang sama di memori, dan tentu saja keduanya :) Untuk meringkas, ingat dan gunakan aturan utama: Untuk membandingkan string, SELALU gunakan sama dengan() metode! Saat membandingkan string, yang Anda maksud hampir selalu adalah membandingkan teksnya, bukan tautan, area memori, dan sebagainya. Metode sama dengan() melakukan apa yang Anda butuhkan. Berikut ini beberapa tautan untuk Anda pelajari sendiri:
GO TO FULL VERSION