Bagaimana cara membandingkan string di Jawa?

724

Saya telah menggunakan ==operator dalam program saya untuk membandingkan semua string saya sejauh ini. Namun, saya menemukan bug, mengubah salah satunya .equals(), dan memperbaiki bug.

Apakah ==buruk? Kapan sebaiknya dan tidak boleh digunakan? Apa bedanya?

Nathan H
sumber
12
Juga bagus untuk mengetahui bahwa, jika Anda meng-override metode .equals (), pastikan Anda meng-override metode .hashcode (), jika tidak, Anda akan berakhir dengan melanggar hubungan ekivalensi b / w sama dengan dan kode hash. Untuk info lebih lanjut, lihat java doc.
Nageswaran
Meninggalkan tautan ke penjelasan saya tentang mengapa ==cara kerjanya seperti pada Objects: stackoverflow.com/a/19966154/2284641
Johannes H.
==akan berfungsi beberapa waktu, karena java memiliki kolam String, di mana ia mencoba untuk menggunakan kembali referensi memori dari string yang biasa digunakan. Tetapi ==membandingkan bahwa objek sama, bukan nilai-nilai ... begitu .equals()juga penggunaan yang tepat yang ingin Anda gunakan.
James Oravec
Jangan pernah menggunakan == untuk menguji apakah Strings sama, kecuali jika Anda menikmati melacak kesalahan halus dan mempelajari seluk-beluk proses magang String Java. "12"=="1"+2false (mungkin)
Penerbangan Odyssey

Jawaban:

5562

== tes untuk persamaan referensi (apakah mereka adalah objek yang sama).

.equals() menguji kesetaraan nilai (apakah secara logis "sama").

Objects.equals () memeriksa nullsebelum memanggil .equals()sehingga Anda tidak perlu (tersedia pada JDK7, juga tersedia di Guava ).

Akibatnya, jika Anda ingin menguji apakah dua string memiliki nilai yang sama, Anda mungkin ingin menggunakannya Objects.equals().

// These two have the same value
new String("test").equals("test") // --> true 

// ... but they are not the same object
new String("test") == "test" // --> false 

// ... neither are these
new String("test") == new String("test") // --> false 

// ... but these are because literals are interned by 
// the compiler and thus refer to the same object
"test" == "test" // --> true 

// ... string literals are concatenated by the compiler
// and the results are interned.
"test" == "te" + "st" // --> true

// ... but you should really just call Objects.equals()
Objects.equals("test", new String("test")) // --> true
Objects.equals(null, "test") // --> false
Objects.equals(null, null) // --> true

Anda hampir selalu ingin menggunakannya Objects.equals(). Dalam situasi langka di mana Anda tahu Anda berurusan dengan string yang diinternir , Anda dapat menggunakannya ==.

Dari JLS 3.10.5. String Literals :

Selain itu, literal string yang selalu mengacu pada yang sama instance dari kelas String. Ini karena string literal - atau, lebih umum, string yang merupakan nilai dari ekspresi konstan ( §15.28 ) - "diinternir" sehingga dapat berbagi contoh yang unik, menggunakan metode ini String.intern.

Contoh serupa juga dapat ditemukan di JLS 3.10.5-1 .

Metode Lain Untuk Dipertimbangkan

String.equalsIgnoreCase () nilai kesetaraan yang mengabaikan case.

String.contentEquals () membandingkan konten Stringdengan konten apa saja CharSequence(tersedia sejak Java 1.5). Menghemat Anda dari keharusan mengubah StringBuffer Anda, dll menjadi String sebelum melakukan perbandingan kesetaraan, tetapi membiarkan null memeriksa Anda.

Aaron Maenpaa
sumber
3
Jika == memeriksa kesetaraan referensi mengapa n == 5 masuk akal? 5 bukan variabel
Hrit Roy
2
@HritRoy Karena ==memeriksa nilai suatu variabel. Ketika Anda memiliki objek, variabel yang mereferensikan objek memiliki referensi objek sebagai nilai . Dengan demikian, Anda membandingkan referensi saat membandingkan dua variabel dengan ==. Ketika membandingkan tipe data primitif seperti int, itu masih kasus yang sama. Variabel tipe intmemiliki integer sebagai nilai. Dengan demikian, Anda membandingkan nilai dua ints menggunakan ==. Jika intnilai variabel atau angka ajaib tidak masalah. Selain itu: Sebuah referensi tidak lain hanyalah sebuah angka yang mengacu pada memori.
akuzminykh
718

==menguji referensi objek, .equals()menguji nilai string.

Kadang-kadang terlihat ==membandingkan nilai, karena Java melakukan beberapa hal di belakang layar untuk memastikan string in-line yang identik sebenarnya adalah objek yang sama.

Sebagai contoh:

String fooString1 = new String("foo");
String fooString2 = new String("foo");

// Evaluates to false
fooString1 == fooString2;

// Evaluates to true
fooString1.equals(fooString2);

// Evaluates to true, because Java uses the same object
"bar" == "bar";

Namun waspadalah terhadap nol!

==menangani nullstring dengan baik, tetapi panggilan .equals()dari string nol akan menyebabkan pengecualian:

String nullString1 = null;
String nullString2 = null;

// Evaluates to true
System.out.print(nullString1 == nullString2);

// Throws a NullPointerException
System.out.print(nullString1.equals(nullString2));

Jadi, jika Anda tahu itu fooString1mungkin nol, beri tahu pembaca bahwa dengan menulis

System.out.print(fooString1 != null && fooString1.equals("bar"));

Berikut ini lebih pendek, tetapi kurang jelas untuk memeriksa null:

System.out.print("bar".equals(fooString1));  // "bar" is never null
System.out.print(Objects.equals(fooString1, "bar"));  // Java 7 required
Whatsit
sumber
86
Kadang-kadang tampak seolah-olah "==" membandingkan nilai-nilai, - == melakukan nilai-nilai selalu membandingkan! (Hanya saja nilai-nilai tertentu adalah referensi!)
aioobe
6
Sayangnya, tidak ada metode statis untuk isNullOrEmpty (), dan tidak ada kustom overloading dari operator, yang membuat bagian dari Java clunkier daripada di C # atau Python. Dan karena Java tidak memiliki metode ekstensi, Anda tidak dapat menulis utilitas Anda sendiri untuk memperluas java.lang.String. Baik? Adakah pemikiran tentang subkelas String, menambahkan metode utilitas statis, dan kemudian selalu menggunakan MyString? Metode statis dengan dua parameter untuk melakukan perbandingan null-safe akan menyenangkan untuk dimiliki dalam subkelas itu juga.
Jon Coombs
7
Groovy menjadikan ini sedikit lebih mudah dengan operator navigasi yang aman ( groovy.codehaus.org/… ) ?.,. Itu akan dikonversi nullString1?.equals(nullString2);menjadi pernyataan yang sepenuhnya nol. Namun, itu tidak membantu jika Anda memiliki validString?.equals(nullString);- itu masih melempar pengecualian.
Charles Wood
5
Metode pendek untuk membandingkan string yang dapat
dibatalkan
5
@JonCoombs Java mendukung metode subclassing dan membuat sendiri. Namun beberapa kelas ditandai final karena alasan tertentu, String adalah salah satunya sehingga kita tidak dapat memperluas. Kita dapat membuat kelas lain dan membuat kelas utilitas di sana yang mengambil dua string sebagai argumen dan mengimplementasikan logika kita di sana. Juga untuk memeriksa null beberapa perpustakaan lain seperti musim semi dan apache dia koleksi metode yang baik, orang dapat menggunakannya.
Panther
442

== membandingkan referensi Objek.

.equals() membandingkan nilai String.

Terkadang ==memberikan ilusi untuk membandingkan nilai String, seperti dalam kasus berikut:

String a="Test";
String b="Test";
if(a==b) ===> true

Ini karena ketika Anda membuat String literal apa pun, JVM pertama mencari literal tersebut di kumpulan String, dan jika menemukan kecocokan, referensi yang sama akan diberikan ke String baru. Karena itu, kita dapat:

(a == b) ===> true

                       String Pool
     b -----------------> "test" <-----------------a

Namun, ==gagal dalam kasus berikut:

String a="test";
String b=new String("test");
if (a==b) ===> false

Dalam hal ini untuk new String("test")pernyataan String baru akan dibuat di heap, dan referensi itu akan diberikan kepada b, jadi bakan diberikan referensi di heap, bukan di string pool.

Sekarang amenunjuk ke String di kolam String sementara bmenunjuk ke String di heap. Karena itu kita dapatkan:

jika (a == b) ===> false.

                String Pool
     "test" <-------------------- a

                   Heap
     "test" <-------------------- b

Meskipun .equals()selalu membandingkan nilai String sehingga memberi benar dalam kedua kasus:

String a="Test";
String b="Test";
if(a.equals(b)) ===> true

String a="test";
String b=new String("test");
if(a.equals(b)) ===> true

Jadi menggunakan .equals()selalu lebih baik.

Ganesh
sumber
3
.equals () membandingkan dua instance namun equals diimplementasikan untuk membandingkannya. Itu mungkin atau mungkin tidak membandingkan output toString.
Yakub
3
@Jacob .equals()Metode kelas objek membandingkan instance (referensi / Alamat) di mana .equals()metode kelas String diganti untuk membandingkan konten (karakter)
Satyadev
1
Bagus menunjukkan kolam String versus perbedaan tumpukan Java karena mereka tentu tidak sama. Dalam kumpulan string Java mencoba "cache" Stringobjek untuk menghemat jejak memori seperti Stringdiketahui tidak berubah (saya harap, saya katakan dengan benar di sini). Juga periksa stackoverflow.com/questions/3052442/...
Roland
1
Ini jawaban yang saya cari.
Weezy
Jawaban yang bagus!
alwbtc
223

The ==cek operator untuk melihat apakah dua string yang persis objek yang sama.

The .equals()Metode akan memeriksa apakah dua string memiliki nilai yang sama.

Clayton
sumber
5
Secara umum saya sangat merekomendasikan perpustakaan apache commons: commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/… , java.lang.String)
Marcin Erbel
179

String di Jawa tidak berubah. Itu berarti setiap kali Anda mencoba mengubah / memodifikasi string Anda mendapatkan contoh baru. Anda tidak dapat mengubah string asli. Ini telah dilakukan sehingga instance string ini dapat di-cache. Sebuah program tipikal berisi banyak referensi string dan caching instance ini dapat mengurangi jejak memori dan meningkatkan kinerja program.

Saat menggunakan operator == untuk perbandingan string, Anda tidak membandingkan konten string, tetapi sebenarnya membandingkan alamat memori. Jika keduanya sama maka akan mengembalikan true dan false sebaliknya. Sedangkan equals in string membandingkan konten string.

Jadi pertanyaannya adalah jika semua string di-cache dalam sistem, mengapa ==return salah sedangkan equal mengembalikan true? Ya, ini mungkin. Jika Anda membuat string baru seperti String str = new String("Testing")Anda akhirnya membuat string baru di cache bahkan jika cache sudah mengandung string yang memiliki konten yang sama. Singkatnya "MyString" == new String("MyString")akan selalu mengembalikan false.

Java juga berbicara tentang fungsi intern () yang dapat digunakan pada string untuk menjadikannya bagian dari cache sehingga "MyString" == new String("MyString").intern()akan mengembalikan true.

Catatan: operator == jauh lebih cepat daripada yang sama hanya karena Anda membandingkan dua alamat memori, tetapi Anda perlu memastikan bahwa kode tersebut tidak membuat instance String baru dalam kode. Kalau tidak, Anda akan menemukan bug.

Faisal Feroz
sumber
147
String a = new String("foo");
String b = new String("foo");
System.out.println(a == b); // prints false
System.out.println(a.equals(b)); // prints true

Pastikan Anda mengerti alasannya. Itu karena ==perbandingan hanya membandingkan referensi; yang equals()metode melakukan perbandingan karakter-karakter dari isi.

Ketika Anda memanggil baru untuk adan b, masing-masing mendapat referensi baru yang menunjuk ke "foo"dalam tabel string. Referensi berbeda, tetapi isinya sama.

Duffymo
sumber
128

Ya itu buruk ...

==berarti bahwa dua referensi string Anda adalah objek yang persis sama. Anda mungkin pernah mendengar bahwa ini adalah kasusnya karena Java menyimpan semacam tabel literal (yang memang demikian), tetapi tidak selalu demikian. Beberapa string dimuat dengan cara yang berbeda, dibuat dari string lain, dll., Jadi Anda tidak boleh berasumsi bahwa dua string identik disimpan di lokasi yang sama.

Sama dengan melakukan perbandingan nyata untuk Anda.

Uri
sumber
124

Ya, ==buruk untuk membandingkan Strings (objek apa pun, kecuali Anda tahu itu kanonik). ==hanya membandingkan referensi objek. .equals()tes untuk kesetaraan. Untuk Strings, seringkali mereka akan sama tetapi seperti yang Anda temukan, itu tidak selalu dijamin.

cletus
sumber
118

Java memiliki kumpulan String di mana Java mengelola alokasi memori untuk objek String. Lihat Kolam Tali di Jawa

Saat Anda memeriksa (membandingkan) dua objek menggunakan ==operator, ia membandingkan kesetaraan alamat ke dalam kumpulan string. Jika dua objek String memiliki referensi alamat yang sama maka kembali true, jika tidak false. Tetapi jika Anda ingin membandingkan konten dari dua objek String maka Anda harus menggantiequals metode.

equals sebenarnya adalah metode kelas Object, tetapi Overridden ke dalam kelas String dan definisi baru diberikan yang membandingkan konten objek.

Example:
    stringObjectOne.equals(stringObjectTwo);

Tapi pikiran menghargai kasus String. Jika Anda ingin membandingkan huruf besar-kecil maka Anda harus menggunakan metode equalsIgnoreCase dari kelas String.

Ayo lihat:

String one   = "HELLO"; 
String two   = "HELLO"; 
String three = new String("HELLO"); 
String four  = "hello"; 

one == two;   // TRUE
one == three; // FALSE
one == four;  // FALSE

one.equals(two);            // TRUE
one.equals(three);          // TRUE
one.equals(four);           // FALSE
one.equalsIgnoreCase(four); // TRUE
Saurabh Agarwal
sumber
7
Saya melihat bahwa ini adalah jawaban terlambat untuk pertanyaan besar. Bolehkah saya bertanya apa yang disediakannya yang belum disebutkan dalam jawaban yang ada?
Mysticial
6
@Mysticial ia telah menambahkan equalsIgnoreCaseyang mungkin informatif untuk yang lebih segar.
AmitG
103

Saya setuju dengan jawaban dari zacherate.

Tapi yang bisa Anda lakukan adalah menelepon intern() string non-literal Anda.

Dari contoh zacherate:

// ... but they are not the same object
new String("test") == "test" ==> false 

Jika Anda magang, persamaan String non-literal adalah true:

new String("test").intern() == "test" ==> true 
pgras
sumber
8
Ini umumnya bukan ide yang baik. Interning relatif mahal dan dapat (secara paradoks) >> meningkatkan << jejak memori JVM Anda dan meningkatkan biaya GC. Dalam kebanyakan kasus, ini lebih besar daripada manfaat kinerja dari penggunaan ==untuk perbandingan string.
Stephen C
101

==membandingkan referensi objek di Jawa , dan itu tidak terkecuali untukString objek.

Untuk membandingkan konten objek yang sebenarnya (termasuk String), seseorang harus menggunakan equalsmetode ini .

Jika perbandingan dua Stringobjek menggunakan ==ternyata true, itu karena Stringobjek diinternir, dan Java Virtual Machine memiliki beberapa titik referensi ke contoh yang sama String. Orang seharusnya tidak berharap bahwa membandingkan satu Stringobjek yang berisi konten yang sama dengan Stringobjek lain gunakan ==untuk mengevaluasi sebagai true.

coobird
sumber
99

.equals() membandingkan data dalam suatu kelas (dengan asumsi fungsi diimplementasikan). ==membandingkan lokasi penunjuk (lokasi objek dalam memori).

==mengembalikan true jika kedua objek (TIDAK BICARA TENTANG PRIMITIF) menunjuk ke instance objek SAMA. .equals()mengembalikan true jika dua objek berisi data yang sama equals()Versus== di Jawa

Itu mungkin bisa membantu Anda.

Matt Razza
sumber
95

==melakukan pemeriksaan kesetaraan referensi , apakah 2 objek (string dalam kasus ini) merujuk ke objek yang sama dalam memori.

The equals()Metode akan memeriksa apakah isi atau negara dari 2 objek yang sama.

Jelas ==lebih cepat, tetapi akan (mungkin) memberikan hasil yang salah dalam banyak kasus jika Anda hanya ingin tahu apakah 2 Strings memegang teks yang sama.

equals()Disarankan penggunaan metode ini.

Jangan khawatir tentang kinerjanya. Beberapa hal untuk didorong menggunakan String.equals():

  1. Implementasi String.equals()pemeriksaan pertama untuk persamaan referensi (menggunakan ==), dan jika 2 string adalah sama dengan referensi, tidak ada perhitungan lebih lanjut yang dilakukan!
  2. Jika referensi 2 string tidak sama, String.equals()selanjutnya akan memeriksa panjang string. Ini juga merupakan operasi cepat karena Stringkelas menyimpan panjang string, tidak perlu menghitung karakter atau poin kode. Jika panjangnya berbeda, tidak ada pemeriksaan lebih lanjut dilakukan, kami tahu mereka tidak bisa sama.
  3. Hanya jika kita sampai sejauh ini maka isi dari 2 string akan benar-benar dibandingkan, dan ini akan menjadi perbandingan singkat: tidak semua karakter akan dibandingkan, jika kita menemukan karakter yang tidak cocok (pada posisi yang sama dalam 2 string) ), tidak ada karakter lebih lanjut akan diperiksa.

Ketika semua dikatakan dan dilakukan, bahkan jika kami memiliki jaminan bahwa string adalah magang, menggunakan equals()metode ini masih tidak overhead yang orang mungkin berpikir, pasti cara yang disarankan. Jika Anda ingin pemeriksaan referensi yang efisien, maka gunakan enums di mana dijamin oleh spesifikasi bahasa dan implementasi bahwa nilai enum yang sama akan menjadi objek yang sama (dengan referensi).

icza
sumber
2
Obviously == is faster- sebenarnya pelaksanaan .equals(String)pemeriksaan pertama ==sebelum hal lain jadi saya akan mengatakan kecepatannya hampir sama.
Razzle Shazl
2
public boolean equals(Object anObject) { if (this == anObject) { return true; } ...
Razzle Shazl
82

Jika Anda seperti saya, ketika saya mulai menggunakan Java, saya ingin menggunakan operator "==" untuk menguji apakah dua instance String sama, tetapi untuk lebih baik atau lebih buruk, itu bukan cara yang tepat untuk melakukannya di Jawa.

Dalam tutorial ini saya akan menunjukkan beberapa cara berbeda untuk membandingkan string Java dengan benar, dimulai dengan pendekatan yang saya gunakan sebagian besar waktu. Di akhir tutorial perbandingan String Java ini saya juga akan membahas mengapa operator "==" tidak berfungsi saat membandingkan string Java.

Opsi 1: Perbandingan Java String dengan metode equals Sebagian besar waktu (mungkin 95% dari waktu) Saya membandingkan string dengan metode equals dari kelas Java String, seperti ini:

if (string1.equals(string2))

Metode String sama dengan ini melihat dua string Java, dan jika mereka berisi string karakter yang sama persis, mereka dianggap sama.

Melihat contoh perbandingan String cepat dengan metode equals, jika tes berikut dijalankan, dua string tidak akan dianggap sama karena karakternya tidak persis sama (kasus karakter berbeda):

String string1 = "foo";
String string2 = "FOO";

if (string1.equals(string2))
{
    // this line will not print because the
    // java string equals method returns false:
    System.out.println("The two strings are the same.")
}

Tetapi, ketika dua string berisi string karakter yang sama persis, metode equals akan mengembalikan true, seperti dalam contoh ini:

String string1 = "foo";
String string2 = "foo";

// test for equality with the java string equals method
if (string1.equals(string2))
{
    // this line WILL print
    System.out.println("The two strings are the same.")
}

Opsi 2: Perbandingan string dengan metode equalsIgnoreCase

Dalam beberapa tes perbandingan string, Anda ingin mengabaikan apakah string dalam huruf besar atau kecil. Saat Anda ingin menguji string Anda untuk kesetaraan dengan cara case-insensitive ini, gunakan metode equalsIgnoreCase dari kelas String, seperti ini:

String string1 = "foo";
String string2 = "FOO";

 // java string compare while ignoring case
 if (string1.equalsIgnoreCase(string2))
 {
     // this line WILL print
     System.out.println("Ignoring case, the two strings are the same.")
 }

Opsi 3: Perbandingan Java String dengan metode compareTo

Ada juga yang ketiga, cara yang kurang umum untuk membandingkan string Java, dan itu dengan metode StringTemper banding kelas. Jika dua string persis sama, metode compareTo akan mengembalikan nilai 0 (nol). Berikut adalah contoh singkat dari apa yang tampak seperti pendekatan perbandingan String ini:

String string1 = "foo bar";
String string2 = "foo bar";

// java string compare example
if (string1.compareTo(string2) == 0)
{
    // this line WILL print
    System.out.println("The two strings are the same.")
}

Sementara saya sedang menulis tentang konsep persamaan di Jawa, penting untuk dicatat bahwa bahasa Jawa mencakup metode yang sama dengan di kelas dasar Java Object. Setiap kali Anda membuat objek Anda sendiri dan Anda ingin memberikan cara untuk melihat apakah dua instance objek Anda "sama", Anda harus menimpa (dan mengimplementasikan) metode yang sama dengan ini di kelas Anda (dengan cara yang sama bahasa Java menyediakan perilaku persamaan / perbandingan ini dalam metode String sama dengan).

Anda mungkin ingin melihat ini ==, .equals (), compareTo (), dan bandingkan ()

Mohamed E. ManSour
sumber
5
untuk string literal Suka String string1 = "foo bar"; String string2 = "foo bar"; Anda dapat langsung menggunakan operator == untuk menguji kesetaraan konten
JAVA
1
Di skrip aplikasi google "compareTo" tidak mungkin. Saya mencoba instaed "equals" Ini adalah satu-satunya solusi yang berfungsi ....
user3887038
77

Fungsi:

public float simpleSimilarity(String u, String v) {
    String[] a = u.split(" ");
    String[] b = v.split(" ");

    long correct = 0;
    int minLen = Math.min(a.length, b.length);

    for (int i = 0; i < minLen; i++) {
        String aa = a[i];
        String bb = b[i];
        int minWordLength = Math.min(aa.length(), bb.length());

        for (int j = 0; j < minWordLength; j++) {
            if (aa.charAt(j) == bb.charAt(j)) {
                correct++;
            }
        }
    }

    return (float) (((double) correct) / Math.max(u.length(), v.length()));
}

Uji:

String a = "This is the first string.";

String b = "this is not 1st string!";

// for exact string comparison, use .equals

boolean exact = a.equals(b);

// For similarity check, there are libraries for this
// Here I'll try a simple example I wrote

float similarity = simple_similarity(a,b);
Khaled.K
sumber
6
Apa bedanya dengan jawaban lain? dan mengapa melakukannya seperti yang Anda sarankan
user151019
2
@ Markus Pertanyaan tentang perbedaan antara ==dan equalssudah dijawab oleh solusi lain, saya hanya menawarkan cara berbeda untuk membandingkan string dengan cara yang longgar
Khaled.K
77

The ==cek Operator jika dua referensi menunjuk ke objek yang sama atau tidak. .equals()periksa konten string yang sebenarnya (nilai).

Perhatikan bahwa .equals()metode ini milik kelas Object(kelas super semua kelas). Anda perlu menimpanya sesuai kebutuhan kelas Anda, tetapi untuk String sudah diterapkan, dan memeriksa apakah dua string memiliki nilai yang sama atau tidak.

  • Kasus 1

    String s1 = "Stack Overflow";
    String s2 = "Stack Overflow";
    s1 == s2;      //true
    s1.equals(s2); //true

    Alasan: String literal yang dibuat tanpa null disimpan di kumpulan String di area permgen heap. Jadi titik s1 dan s2 baik untuk objek yang sama di kolam renang.

  • Kasus 2

    String s1 = new String("Stack Overflow");
    String s2 = new String("Stack Overflow");
    s1 == s2;      //false
    s1.equals(s2); //true

    Alasan: Jika Anda membuat objek String menggunakan newkata kunci, ruang terpisah dialokasikan untuk itu di heap.

Aniket Thakur
sumber
53

==membandingkan nilai referensi objek sedangkan equals()metode yang ada di java.lang.Stringkelas membandingkan konten Stringobjek (dengan objek lain).

samkit shah
sumber
15
bukan untuk pilih-pilih, tetapi equals()metode untuk Stringsebenarnya di Stringkelas, bukan di Object. Default equals()di Objecttidak akan membandingkan bahwa isinya sama, dan pada kenyataannya hanya mengembalikan true ketika referensi sama.
Jacob Schoen
1
@JacobSchoen: Tautan di atas tidak berfungsi lagi karena GrepCode sedang down. Berikut ini adalah alternatif untuk penerapan yang sama: [Tautan Inline] ( zgrepcode.com/java/openjdk/10.0.2/java.base/java/lang/… )
Amandeep Singh
50

Saya pikir ketika Anda mendefinisikan StringAnda mendefinisikan sebuah objek. Jadi, Anda perlu menggunakan .equals(). Saat Anda menggunakan tipe data primitif yang Anda gunakan ==tetapi dengan String(dan objek apa pun) yang harus Anda gunakan .equals().

fabricioflores
sumber
7
"char []" bukan tipe data primitif! Ini adalah array "char". Dan array bukan tipe data primitif sendiri.
Christian
48

Jika equals()metode hadir di java.lang.Objectkelas, dan diharapkan untuk memeriksa kesetaraan keadaan objek! Itu artinya, isi benda. Sedangkan== operator diharapkan memeriksa instance objek yang sebenarnya sama atau tidak.

Contoh

Pertimbangkan dua variabel referensi yang berbeda, str1dan str2:

str1 = new String("abc");
str2 = new String("abc");

Jika Anda menggunakan equals()

System.out.println((str1.equals(str2))?"TRUE":"FALSE");

Anda akan mendapatkan output seperti TRUEjika Anda gunakan ==.

System.out.println((str1==str2) ? "TRUE" : "FALSE");

Sekarang Anda akan mendapatkan FALSEoutput sebagai, karena keduanya str1dan str2menunjuk ke dua objek yang berbeda walaupun keduanya berbagi konten string yang sama. Itu karena new String()objek baru dibuat setiap saat.

Rakesh KR
sumber
43

Operator == selalu dimaksudkan untuk perbandingan referensi objek , sedangkan metode kelas String .equals () diganti untuk perbandingan konten :

String s1 = new String("abc");
String s2 = new String("abc");
System.out.println(s1 == s2); // It prints false (reference comparison)
System.out.println(s1.equals(s2)); // It prints true (content comparison)
sham.y
sumber
40

Semua objek dijamin memiliki .equals()metode karena Objek berisi metode .equals(),, yang mengembalikan boolean. Adalah tugas subclass untuk menimpa metode ini jika definisi definisi lebih lanjut diperlukan. Tanpa itu (yaitu menggunakan ==) hanya alamat memori yang diperiksa antara dua objek untuk kesetaraan. String menimpa .equals()metode ini dan alih-alih menggunakan alamat memori, String mengembalikan perbandingan string pada level karakter untuk kesetaraan.

Catatan utama adalah bahwa string disimpan dalam satu kumpulan benjolan sehingga setelah sebuah string dibuat, string tersebut selamanya disimpan dalam sebuah program di alamat yang sama. String tidak berubah, mereka tidak berubah. Inilah sebabnya mengapa itu adalah ide yang buruk untuk menggunakan penggabungan string biasa jika Anda memiliki jumlah serius pemrosesan string yang harus dilakukan. Sebagai gantinya Anda akan menggunakan StringBuilderkelas yang disediakan. Ingat pointer ke string ini dapat berubah dan jika Anda tertarik untuk melihat apakah dua pointer itu sama ==akan menjadi cara yang baik untuk pergi. String sendiri tidak.

James
sumber
2
"Begitu sebuah string dibuat, selamanya disimpan dalam sebuah program di alamat yang sama" - Ini benar-benar salah. Hanya ekspresi string konstan waktu kompilasi (mungkin melibatkan final Stringvariabel) dan string yang program Anda secara magang disimpan dalam apa yang Anda sebut "kumpulan benjolan". Semua Stringobjek lain tunduk pada pengumpulan sampah begitu tidak ada lagi referensi langsung ke mereka, sama seperti jenis objek lainnya. Selain itu, sementara ketidakmampuan diperlukan untuk keseluruhan mekanisme magang untuk bekerja, itu tidak relevan dengan ini.
Ted Hopp
Perbandingan string dilakukan melalui metode equals atau equalsIgnoreCase yang benar-benar membandingkan isi string. Tapi tanda == cukup periksa nilai referensi. Untuk string literal dari string pool akan berfungsi dengan baik untuk kasus ini. String s1 = String baru ("a"); String s2 = String baru ("a"); dalam hal ini s1 == s2 adalah salah, tetapi s1.equals (s2) benar.
Shailendra Singh
39

Anda juga dapat menggunakan compareTo()metode ini untuk membandingkan dua String. Jika hasil compareTo adalah 0, maka kedua string sama, jika tidak, string yang dibandingkan tidak sama.

Yang ==membandingkan referensi dan tidak membandingkan string yang sebenarnya. Jika Anda memang membuat setiap string menggunakan new String(somestring).intern()maka Anda dapat menggunakan ==operator untuk membandingkan dua string, jika tidak sama dengan () atau metode compareTo hanya dapat digunakan.

AlvaroAV
sumber
35

Di Jawa, ketika operator “==” digunakan untuk membandingkan 2 objek, ia memeriksa untuk melihat apakah objek merujuk ke tempat yang sama di memori. Dengan kata lain, itu memeriksa untuk melihat apakah 2 nama objek pada dasarnya referensi ke lokasi memori yang sama.

Kelas Java String benar-benar menimpa implementasi default equals () di kelas Object - dan itu menimpa metode sehingga hanya memeriksa nilai-nilai string, bukan lokasi mereka di memori. Ini berarti bahwa jika Anda memanggil metode equals () untuk membandingkan 2 objek String, maka selama urutan karakter sebenarnya sama, kedua objek dianggap sama.

The ==cek Operator jika dua string yang persis objek yang sama.

The .equals()metode cek jika dua string memiliki nilai yang sama.

Lijo
sumber
1
kecuali salah satunya adalah nol, karena s.equals (s2) akan macet jika s adalah nol, menyebabkan perbandingan gagal. Tentu saja, ini tidak benar-benar bertentangan dengan jawabannya; itu hanya peringatan.
Jon Coombs
1
Tidak, itu tidak akan crash, itu akan melempar NullPointerException, menyebabkan perbandingan tidak terjadi.
Bludzee