CodeGym /Java Blog /Acak /Bandingkan perbandingan String dan Sama dengan di Jawa
John Squirrels
Level 41
San Francisco

Bandingkan perbandingan String dan Sama dengan di Jawa

Dipublikasikan di grup Acak
Hai! Hari ini kita akan membahas topik yang sangat penting dan menarik yaitu membandingkan objek dengan objek (Bandingkan String dan Persamaan). Jadi di Jawa, kapan tepatnya objek A 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: salah Tunggu, berhenti. Mengapa kedua mobil ini tidak sama? Kami memberi mereka properti yang sama, tetapi hasil perbandingannya salah. Jawabannya sederhana. Operator == membandingkan referensi objek, bukan properti objek. Dua objek bahkan dapat memiliki 500 bidang dengan nilai yang identik, tetapi membandingkannya masih akan menghasilkan kesalahan. Lagi pula, referensi mobil1 dan mobil2arahkan ke dua objek yang berbeda, yaitu ke dua alamat yang berbeda. Bayangkan situasi di mana Anda membandingkan orang. Tentu saja, di suatu tempat di dunia ada seseorang yang memiliki nama, warna mata, usia, tinggi, warna rambut, dll yang sama dengan Anda. Itu membuat Anda serupa dalam banyak hal, tetapi Anda tetap bukan kembar — dan Anda jelas bukan kembar orang yang sama.
Persamaan dan perbandingan string - 2
Operator == menggunakan logika yang kurang lebih sama saat kita menggunakannya untuk membandingkan dua objek. Tetapi bagaimana jika Anda membutuhkan program Anda untuk menggunakan logika yang berbeda? Misalnya, misalkan program Anda melakukan analisis DNA. Itu membandingkan kode genetik dua orang, dan menentukan apakah mereka kembar.

public class Man {

   int geneticCode;

   public static void main(String[] args) {

       Man man1 = new Man();
       man1.geneticCode = 1111222233;

       Man man2 = new Man();
       man2.geneticCode = 1111222233;

       System.out.println(man1 == man2);
   }
}
Keluaran konsol: false Kami mendapatkan hasil logis yang sama (karena kami tidak banyak berubah), tetapi sekarang logika itu tidak bagus! Lagi pula, dalam kehidupan nyata, analisis DNA seharusnya memberi kita jaminan 100% bahwa kita memiliki anak kembar yang berdiri di depan kita. Tetapi program kami dan operator == memberi tahu kami sebaliknya. Bagaimana kita mengubah perilaku ini dan memastikan program mengeluarkan hasil yang benar ketika DNA cocok? Java memiliki metode khusus untuk ini: equals() . Seperti metode toString() , yang telah kita bahas sebelumnya, equals() milik kelas Object — kelas paling penting di Java, kelas asal semua kelas lainnya. Tapi sama dengan()tidak mengubah perilaku program kita dengan sendirinya:

public class Man {

   String geneticCode;

   public static void main(String[] args) {

       Man man1 = new Man();
       man1.geneticCode = "111122223333";

       Man man2 = new Man();
       man2.geneticCode = "111122223333";

       System.out.println(man1.equals(man2));
   }
}
Output konsol: false Hasil yang persis sama, jadi untuk apa kita membutuhkan metode ini? :/ Semuanya sederhana. Masalahnya di sini adalah saat ini kami menggunakan metode ini seperti yang diterapkan di kelas Object . Dan jika kita masuk ke kode kelas Object dan melihat penerapan metodenya, inilah yang akan kita lihat:

public boolean equals(Object obj) {
   return (this == obj);
}
Itulah alasan mengapa perilaku program tidak berubah! Operator == yang sama (yang membandingkan referensi) digunakan di dalam metode equals() dari kelas Object . Tapi trik dengan metode ini adalah kita bisa menimpanya. Mengganti berarti menulis metode equals() Anda sendiri di kelas Man kita , memberikannya perilaku yang kita butuhkan! Saat ini, kami tidak menyukai fakta bahwa man1.equals(man2) pada dasarnya setara dengan 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: benar Sekarang kita mendapatkan hasil yang sama sekali berbeda! Dengan menulis metode equals() kita sendiri dan menggunakannya alih-alih yang standar, kita telah menghasilkan perilaku yang benar: Sekarang jika dua orang memiliki DNA yang sama, program akan melaporkan "Analisis DNA telah membuktikan bahwa mereka kembar" dan hasilnya benar! Dengan mengganti metode equals() di kelas Anda, Anda dapat dengan mudah membuat logika perbandingan objek apa pun yang Anda butuhkan. Faktanya, kita baru saja menyentuh perbandingan objek. Di depan kita, masih ada pelajaran besar yang berdiri sendiri tentang topik ini (Anda membaca sepintas lalu jika Anda tertarik).

Membandingkan string di Jawa

Mengapa kami mempertimbangkan perbandingan string secara terpisah dari yang lainnya? Kenyataannya adalah bahwa string adalah subjek tersendiri dalam pemrograman. Pertama, jika Anda mengambil semua program Java yang pernah ditulis, Anda akan menemukan bahwa sekitar 25% objek di dalamnya adalah string. Jadi topik ini sangat penting. Kedua, proses membandingkan string sangat berbeda dengan objek lain. Pertimbangkan contoh sederhana:

public class Main {

   public static void main(String[] args) {

       String s1 = "CodeGym is the best website for learning Java!";
       String s2 = new String("CodeGym is the best website for learning Java!");
       System.out.println(s1 == s2);
   }
}
Keluaran konsol: salah Tapi mengapa kita salah? Lagi pula, stringnya persis sama, kata demi kata :/ Anda mungkin sudah bisa menebak alasannya: itu karena operator == membandingkan referensi ! Jelas, s1 dan s2 memiliki alamat berbeda di memori. Jika Anda memikirkannya, mari kita ulang contoh kita:

public class Main {

   public static void main(String[] args) {

       String s1 = "CodeGym is the best website for learning Java!";
       String s2 = "CodeGym is the best website for learning Java!";
       System.out.println(s1 == s2);
   }
}
Sekarang kami kembali memiliki dua referensi, tetapi hasilnya justru sebaliknya: Keluaran konsol: benar Bingung tak berdaya? Mari kita cari tahu apa yang terjadi. Operator == benar-benar membandingkan alamat memori. Ini selalu benar dan Anda tidak perlu meragukannya. Itu berarti jika s1 == s2 mengembalikan true, maka kedua string ini memiliki alamat yang sama. Dan memang ini benar! Saatnya memperkenalkan Anda ke area memori khusus untuk menyimpan string: kumpulan string
Persamaan dan perbandingan string - 3
Kumpulan string adalah area untuk menyimpan semua nilai string yang Anda buat dalam program Anda. Mengapa itu dibuat? Seperti yang kami katakan sebelumnya, string mewakili persentase yang sangat besar dari semua objek. Program besar apa pun membuat banyak string. Kumpulan string dibuat untuk menghemat memori: string ditempatkan di sana dan kemudian string yang dibuat merujuk ke area memori yang sama—tidak perlu mengalokasikan memori tambahan setiap kali. Setiap kali Anda menulis String = "........" program memeriksa apakah ada string yang identik di kumpulan string. Jika ada, maka string baru tidak akan dibuat. Dan referensi baru akan menunjuk ke alamat yang sama di kumpulan string (tempat string yang identik berada). Jadi ketika kita menulis

String s1 = "CodeGym is the best website for learning Java!";
String s2 = "CodeGym is the best website for learning Java!";
s2 menunjuk ke tempat yang sama dengan s1 . Pernyataan pertama membuat string baru di kumpulan string. Pernyataan kedua hanya mengacu pada area memori yang sama dengan s1 . Anda dapat membuat 500 string identik lainnya dan hasilnya tidak akan berubah. Tunggu sebentar. Jika itu benar, mengapa contoh ini tidak berhasil sebelumnya?

public class Main {

   public static void main(String[] args) {

       String s1 = "CodeGym is the best website for learning Java!";
       String s2 = new String("CodeGym is the best website for learning Java!");
       System.out.println(s1 == s2);
   }
}
Saya pikir intuisi Anda telah memberi tahu Anda alasannya =) Coba tebak sebelum membaca lebih lanjut. Anda dapat melihat bahwa kedua string ini dideklarasikan dengan cara yang berbeda. Satu dengan operator baru, dan yang lainnya tanpa itu. Di sinilah letak alasannya. Saat operator baru digunakan untuk membuat objek, ia secara paksa mengalokasikan area memori baru untuk objek tersebut. Dan sebuah string yang dibuat menggunakan new tidak berakhir di kumpulan string — itu menjadi objek terpisah, bahkan jika teksnya sangat cocok dengan string di kumpulan string. Yaitu, jika kita menulis kode berikut:

public class Main {

   public static void main(String[] args) {

       String s1 = "CodeGym is the best website for learning Java!";
       String s2 = "CodeGym is the best website for learning Java!";
       String s3 = new String("CodeGym is the best website for learning Java!");
   }
}
Dalam memori, tampilannya seperti ini:
Persamaan dan perbandingan string - 4
Dan setiap kali Anda membuat objek baru menggunakan new , area memori baru dialokasikan, meskipun teks di dalam string baru itu sama! Sepertinya kita sudah menemukan operator == . Tapi bagaimana dengan kenalan baru kita, metode equals() ?

public class Main {

   public static void main(String[] args) {

       String s1 = "CodeGym is the best website for learning Java!";
       String s2 = new String("CodeGym is the best website for learning Java!");
       System.out.println(s1.equals(s2));
   }
}
Keluaran konsol: benar Menarik. Kami yakin bahwa s1 dan s2 menunjuk ke area berbeda dalam memori. Tetapi metode equals() masih memberi tahu kita bahwa keduanya sama. Mengapa? Ingat kita sebelumnya mengatakan bahwa metode equals() dapat diganti untuk membandingkan objek sesuai keinginan kita? Itulah yang telah mereka lakukan dengan kelas String . Itu menimpa yang sama dengan ()metode. Dan alih-alih membandingkan referensi, ini membandingkan urutan karakter dalam string. Jika teksnya sama, tidak masalah bagaimana mereka dibuat atau di mana mereka disimpan: apakah di kumpulan string atau area memori yang terpisah. Hasil perbandingan akan benar. By the way, Java memungkinkan Anda melakukan perbandingan string case-insensitive. Biasanya, jika salah satu string memiliki huruf besar semua, maka hasil perbandingannya akan salah:

public class Main {

   public static void main(String[] args) {

       String s1 = "CodeGym is the best website for learning Java!";
       String s2 = new String("CODEGYM IS THE BEST WEBSITE FOR LEARNING JAVA!");
       System.out.println(s1.equals(s2));
   }
}
Output konsol: false Untuk perbandingan case-insensitive, kelas String memiliki metode equalsIgnoreCase() . Anda dapat menggunakannya jika Anda hanya ingin membandingkan urutan karakter tertentu daripada huruf besar-kecil. Misalnya, ini dapat membantu saat membandingkan dua alamat:

public class Main {

   public static void main(String[] args) {

       String address1 = "2311 Broadway Street, San Francisco";
       String address2 = new String("2311 BROADWAY STREET, SAN FRANCISCO");
       System.out.println(address1.equalsIgnoreCase(address2));
   }
}
Dalam hal ini, jelas kita berbicara tentang alamat yang sama, jadi masuk akal untuk menggunakan metode equalsIgnoreCase() .

Metode String.intern()

Kelas String memiliki satu lagi metode rumit: intern() ; Metode intern() bekerja langsung dengan kumpulan string. Jika Anda memanggil metode intern() pada beberapa string:
  • Itu memeriksa apakah ada string yang cocok di kumpulan string
  • Jika ada, itu mengembalikan referensi ke string di kumpulan
  • Jika tidak, itu menambahkan string ke kumpulan string dan mengembalikan referensi ke sana.
Setelah menggunakan metode intern() pada referensi string yang diperoleh menggunakan new , kita dapat menggunakan operator == untuk membandingkannya dengan referensi string dari kumpulan string.

public class Main {

   public static void main(String[] args) {

       String s1 = "CodeGym is the best website for learning Java!";
       String s2 = new String("CodeGym is the best website for learning Java!");
       System.out.println(s1 == s2.intern());
   }
}
Keluaran konsol: true Ketika kami membandingkan string ini sebelumnya tanpa intern() , hasilnya salah. Sekarang metode intern() memeriksa apakah string "CodeGym adalah situs terbaik untuk mempelajari Java!" ada di kolam tali. Tentu saja: kami membuatnya dengan

String s1 = "CodeGym is the best website for learning Java!";
Kami memeriksa apakah s1 dan referensi yang dikembalikan oleh s2.intern() mengarah ke area memori yang sama. Dan tentu saja, mereka melakukannya :) Ringkasnya, hafalkan dan terapkan aturan penting ini: SELALU gunakan metode equals() untuk membandingkan string! Saat membandingkan string, kami hampir selalu bermaksud membandingkan karakternya daripada referensi, area memori, atau apa pun. Metode equals() melakukan apa yang Anda butuhkan. Untuk memperkuat apa yang Anda pelajari, kami sarankan Anda menonton video pelajaran dari Kursus Java kami

Lebih banyak bacaan:

Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION