Perbedaan antara metode String # equals dan String # contentEquals

Jawaban:

171

Tidak String#equals()hanya membandingkan isi String, tetapi juga memeriksa apakah objek lain juga merupakan instance dari a String. The String#contentEquals()hanya membandingkan isi (urutan karakter) dan tidak tidak memeriksa apakah benda lain juga merupakan contoh dari String. Itu bisa apa saja asalkan merupakan implementasi dari CharSequenceyang mencakup ao String, StringBuilder, StringBuffer, CharBuffer, dll

BalusC
sumber
12
Jadi, apakah ini seperti operator ==(contentEquals) dan ===(equals) dalam javascript?
anestv
2
@ anestv Di Jawa, ==operator hanya akan mengizinkan Anda membandingkan referensi, bukan konten dari dua objek.
Stephan
2
@Alex untuk memperjelas, operator == di Jawa adalah untuk memeriksa apakah dua objek menunjuk ke lokasi yang sama dalam memori, atau apakah dua tipe primitif (byte, pendek, int, panjang, float, ganda, char, boolean) sama.
La-comadreja
2
@Stephan, yang ==disebutkan hanyalah JavaScript; tidak pernah disebutkan tentang Java.
Olathe
@ anestv, ada perbedaan ( ==dalam JavaScript jauh lebih longgar daripada contentEquals, yang tidak akan menyentuh angka, misalnya), tetapi Anda benar tentang equalsmemeriksa kecocokan jenis yang tepat denganStrings (kelas lain mungkin lebih longgar dengan jenis dalam equalsmetode mereka ) .
Olathe
43

Sederhananya: String.contentEquals()adalah saudara yang lebih pintar String.equals(), karena bisa lebih bebas dalam implementasi daripada String.equals().

Ada beberapa alasan mengapa ada String.contentEquals()metode terpisah . Alasan terpenting yang saya pikirkan adalah:

  • The equalsMetode harus refleksif. Itu berarti bahwa: x.equals(y) == y.equals(x). Ini berarti bahwa aString.equals(aStringBuffer)harus sama dengan aStringBuffer.equals(aString). Ini akan membutuhkan pengembang Java API untuk membuat beberapa implementasi khusus untuk Strings dalam equals()metode StringBuffer, StringBuilder dan CharSequence juga. Ini akan berantakan.

Di sinilah String.contentEqualsmasuk. Ini adalah metode mandiri yang tidak tidak harus mengikuti persyaratan yang ketat dan aturan untuk Object.equals. Dengan cara ini, Anda dapat menerapkan rasa "konten yang sama" lebih bebas. Ini memungkinkan Anda untuk membuat perbandingan cerdas antara StringBuffer dan String, misalnya.

Dan untuk mengatakan apa sebenarnya perbedaannya adalah:

  • String.contentEquals()dapat membandingkan konten dari a String, a StringBuilder, a StringBuffer, a, CharSequencedan semua kelas turunannya. Jika parameternya bertipe String, maka String.equals()jalankan.

  • String.equals()hanya membandingkan objek String. Semua jenis objek lainnya dianggap tidak sama.

  • String.contentEquals()dapat membandingkan StringBufferdan StringBuilderdengan cara yang cerdas. Itu tidak memanggil toString()metode berat , yang menyalin seluruh konten ke objek String baru. Sebaliknya, ia membandingkan dengan char[]array yang mendasarinya , yang sangat bagus.

Martijn Courteaux
sumber
31

Jawaban ini sudah diposting oleh dbw tetapi dia menghapusnya tetapi dia memiliki beberapa poin yang sangat valid untuk perbedaan sambil membandingkan waktu eksekusi, pengecualian apa yang dilemparkan,

Jika Anda melihat kode sumber String # equals dan String # contentEquals jelas bahwa ada dua metode yang diganti untuk String#contentEqualssatu yang mengambil StringBuilderdan yang lainnya CharSequence.
Perbedaan di antara mereka,

  1. String#contentEqualsakan melempar NPE jika argumen yang diberikan adalah nulltetapi String#equalsakan kembalifalse
  2. String#equalsmembandingkan konten hanya ketika argumen yang diberikan adalah instance of Stringsebaliknya akan kembali falsedalam semua kasus lain tetapi di sisi lain String#contentEqualsmemeriksa konten semua objek yang mengimplementasikan antarmuka CharSequence.
  3. Anda juga dapat mengubah kode sehingga String#contentEqualsmengembalikan hasil atau hasil yang salah yang Anda inginkan dengan equalsmengganti metode argumen yang diteruskan seperti yang ditunjukkan di bawah ini tetapi Anda tidak dapat melakukan tweak dengan String#equals.
    Kode di bawah ini akan selalu menghasilkantrue selama sberisi stringyang panjangnya 3 karakter

        String s= new String("abc");// "abc";
        System.out.println(s.contentEquals(new CharSequence() 
        {
    
            @Override
            public CharSequence subSequence(int arg0, int arg1) {
                // TODO Auto-generated method stub
                return null;
            }
    
            @Override
            public int length() {
                // TODO Auto-generated method stub
                return 0;
            }
    
            @Override
            public char charAt(int arg0) {
                // TODO Auto-generated method stub
                return 0;
            }
    
    
            @Override
            public boolean equals(Object obj) 
            {
               return true;
            }
        }));
  4. String#contentEqualsakan lebih lambat maka String#Equalsdalam kasus ketika argumen yang diberikan adalah instance of Stringdan panjang keduanya Stringsama tetapi isinya tidak sama.
    Contoh jika string String s = "madam"dan String argPassed = "madan"kemudian s.contentEquals(argPassed)akan memakan waktu hampir dua kali lipat waktu eksekusi dalam kasus ini dibandingkan dengans.equals(argPassed)

  5. Jika panjang konten tidak sama untuk kedua string maka fungsinya String#contentEqualsakan memiliki kinerja yang lebih baik maka String#Equalsdalam hampir semua kasus mungkin.

Satu hal lagi untuk menambah jawabannya

  1. String#contentEqualssuatu Stringobjek juga akan membandingkan dengan StringBuilderkonten dan memberikan hasil yang sesuai saat String#Equalsakan kembalifalse
Prateek
sumber
4
@dbw jawaban ini berasal dari jawaban yang Anda poskan
Prateek
@dbw Selain itu, mengapa Anda menghapus postingan Anda?
MC Emperor
14
  • Stringequals(Object o)metode kelas hanya melakukan Stringperbandingan. Tetapi contentEquals(CharSequence cs)pemeriksaan untuk kelas mencakup AbstractStringBuilderie StringBuffer, StringBuilderdan Stringjuga kelas (Mereka semua bertipe CharSequence).

    String str = "stackoverflow";
    StringBuilder builder = new StringBuilder(str);
    System.out.println(str.equals(builder));
    System.out.println(str.contentEquals(builder));

keluaran:

false
true

Output dari stmt pertama adalah falsekarena builderbukan tipe Stringbegitu equals()kembali falsetetapi contentEquals()pemeriksaan atas isi dari semua jenis seperti StringBuilder, StringBuffer, Stringdan dengan konten yang sama maka true.

  • contentEqualsakan melempar NullPointerExceptionjika argumen yang diberikan adalah nulltetapi equals()akan mengembalikan false karena equals () memeriksa instanceOf ( if (anObject instance of String)) yang mengembalikan false jika argumen tersebut null.
Mencoba
sumber
14

contentEquals(CharSequence cs):

  • Memungkinkan Anda memeriksa kesetaraan nilai string yang diberikan dengan implementasi contoh dari antarmuka java.lang.CharacterSequence(misalnya, CharBuffer, Segment, String, StringBuffer, StringBuilder)

equals(Object anObject):

  • Memungkinkan Anda memeriksa kesetaraan nilai string yang diberikan dengan sembarang jenis ketik java.lang.String saja

RTFC :)

Karena membaca sumber adalah cara terbaik untuk memahaminya, saya membagikan implementasi dari kedua metode (pada jdk 1.7.0_45)

public boolean contentEquals(CharSequence cs) {
    if (value.length != cs.length())
        return false;
    // Argument is a StringBuffer, StringBuilder
    if (cs instanceof AbstractStringBuilder) {
        char v1[] = value;
        char v2[] = ((AbstractStringBuilder) cs).getValue();
        int i = 0;
        int n = value.length;
        while (n-- != 0) {
            if (v1[i] != v2[i])
                return false;
            i++;
        }
        return true;
    }
    // Argument is a String
    if (cs.equals(this))
        return true;
    // Argument is a generic CharSequence
    char v1[] = value;
    int i = 0;
    int n = value.length;
    while (n-- != 0) {
        if (v1[i] != cs.charAt(i))
            return false;
        i++;
    }
    return true;
}

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String) anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                        return false;
                i++;
            }
            return true;
        }
    }
    return false;
 }

Ada metode lain dari String # contentEquals ():

public boolean contentEquals(StringBuffer sb) {
    synchronized(sb) {
        return contentEquals((CharSequence)sb);
    }
}
Amit Sharma
sumber
9

equals()dan contentEquals()dua metode di Stringkelas untuk membandingkan dua stringsdan stringdengan StringBuffer.

Parameter contentEquals()are StringBufferdan String(charSequence). equals()digunakan untuk membandingkan dua stringsdan contentEquals()digunakan untuk membandingkan konten Stringdan StringBuffer.

Metode contentEqualsdan equalsyang

public boolean contentEquals(java.lang.StringBuffer);
public boolean contentEquals(java.lang.CharSequence);
public boolean equals(Object o)

Berikut adalah kode yang menjelaskan kedua metode tersebut

public class compareString {
    public static void main(String[] args) {
        String str1 = "hello";    
        String str2 = "hello";

        StringBuffer sb1 = new StringBuffer("hello");
        StringBuffer sb2 = new StringBuffer("world");

        boolean result1 = str1.equals(str2);        // works nice and returns true
        System.out.println(" str1.equals(str2) - "+ result1);

        boolean result2 = str1.equals(sb1);         // works nice and returns false
        System.out.println(" str1.equals(sb1) - "+ result2);

        boolean result3 = str1.contentEquals(sb1);  // works nice and returns true
        System.out.println(" str1.contentEquals(sb1) - "+ result3);

        boolean result4 = str1.contentEquals(sb2);  // works nice and returns false
        System.out.println(" str1.contentEquals(sb2) - "+ result4);

        boolean result5 = str1.contentEquals(str2);  // works nice and returns true
        System.out.println(" str1.contentEquals(str2) - "+ result5);
    }
}

Keluaran:

 str1.equals(str2) - true
 str1.equals(sb1) - false
 str1.contentEquals(sb1) - true
 str1.contentEquals(sb2) - false
 str1.contentEquals(str2) - true
Asfab
sumber
7

String # equals mengambil Object sebagai argumen dan memeriksa apakah instance dari objek String atau tidak. Jika objek argumen adalah Objek String maka ia membandingkan konten karakter dengan karakter. Ini mengembalikan true jika konten dari kedua objek string sama.

String # contentEquals mengambil antarmuka CharSequence sebagai argumen. CharSequence dapat diimplementasikan dalam 2 cara-dengan menggunakan i) kelas String atau (ii) AbstractStringBuilder (kelas induk dari StringBuffer, StringBuilder)

Dalam contentEquals () panjang dibandingkan sebelum pemeriksaan instance objek. Jika panjangnya sama maka ia memeriksa objek argumen adalah instance dari AbstractStringBuilder atau tidak. Jika demikian (mis. StringBuffer atau StringBuilder) maka konten diperiksa karakter demi karakter. Dalam kasus argumen adalah turunan dari objek String maka String # sama dengan dipanggil dari String # contentEquals.

Singkatnya,

String # sama dengan membandingkan karakter konten dengan karakter dalam argumen kasus adalah objek String juga. Dan String # contentEquals membandingkan konten jika objek argumen mengimplementasikan antarmuka CharSequence.

String # contentEquals lebih lambat jika kita membandingkan dua konten string panjang yang sama dengan String # contentEquals secara internal memanggil String # sama dengan untuk objek String.

Jika kita mencoba membandingkan objek dengan panjang konten yang berbeda (katakan "abc" dengan "abcd") maka String # contentEquals lebih cepat daripada String # equals. Karena panjang dibandingkan sebelum objek misalnya memeriksa.

Anirban Pal
sumber
6

The contentEquals()Metode pemeriksaan adalah isinya sama antara String, StringBuffer, dll yang semacam urutan arang.

fastcodejava
sumber
5

BTW, alasan historis untuk perbedaan adalah bahwa String awalnya tidak memiliki superclass, jadi String.equals () mengambil String sebagai argumennya. Ketika CharSequence diperkenalkan sebagai superclass of String, ia membutuhkan tes kesetaraan sendiri yang bekerja di semua implementasi CharSequence, dan yang tidak akan bertabrakan dengan equals () yang sudah digunakan oleh String ... jadi kami mendapat CharSequence.contentEquals ( ), yang diwarisi oleh String.

Jika CharSequence telah ada di Java 1.0, kami mungkin hanya memiliki CharSequence.equals () dan String hanya akan mengimplementasikannya.

Ah, kegembiraan bahasa yang berkembang ...

keshlam
sumber