String # equals ile String # contentEquals yöntemleri arasındaki fark


Yanıtlar:


179

String#equals()Diğer bir amacı da bir örneği ise String'in içerikleri değil, aynı zamanda kontrolleri karşılaştırır sadece String. String#contentEquals()Sadece içeriği (karakter dizisi) karşılaştırır ve etmez olmayan diğer bir amacı, aynı zamanda, bir örneği olup olmadığını kontrol String. Bunun bir uygulamasıdır gibi sürece herhangi bir şey olabilir CharSequenceao kapsayan String, StringBuilder, StringBuffer, CharBuffer, vb


13
Peki, javascript'teki operatörler ==(contentEquals) ve ===(equals) gibi mi?
anestv

2
@anestv Java'da ==operatör , iki nesnenin içeriğini değil, yalnızca referansları karşılaştırmanıza izin verir .
Stephan

2
@Alex açıklamak gerekirse, Java'daki == operatörü, iki nesnenin bellekte aynı konumu gösterip göstermediğini veya iki ilkel türün (bayt, kısa, int, uzun, float, double, char, boolean) eşit olup olmadığını kontrol etmek içindir.
La-comadreja

2
@Stephan, ==bahsedilen sadece JavaScript; Java ile ilgili hiç bahsedilmiyor.
Olathe

@anestv, orada farklar (Hangi ==JavaScript göre çok daha gevşek olduğu contentEquals, örneğin sayılar dokunmaz,), ama yaklaşık sen doğru equalstam bir tip maç için denetleme ileStrings (diğer sınıflar kendi içinde türleri ile gevşek olabilir equalsyöntemlerle) .
Olathe

49

Kolayca söylemek gerekirse: String.contentEquals()daha akıllı kardeşidir String.equals(), çünkü uygulamada daha özgür olabilir String.equals().

Ayrı bir String.contentEquals()yöntemin olmasının bazı nedenleri var . Düşünmemin en önemli nedeni şudur:

  • equalsYöntem dönüşlü olmak zorundadır. Bunun anlamı şu: x.equals(y) == y.equals(x). Bu, bunun ile aString.equals(aStringBuffer)aynı olması gerektiği anlamına gelir aStringBuffer.equals(aString). Bu, Java API geliştiricilerinin equals()StringBuffer, StringBuilder ve CharSequence yöntemlerinde de Strings için bazı özel uygulamalar yapmasını gerektirir . Bu tam bir karmaşa olurdu.

Bu noktada String.contentEqualsgeliyor. Bu bir bağımsız yöntemi yok değil zorunda sıkı gereksinimleri ve kuralları takip için Object.equals. Bu şekilde, "eşit içerik" duygusunu daha özgürce uygulayabilirsiniz . Bu, örneğin bir StringBuffer ve String arasında akıllı karşılaştırmalar yapmanızı sağlar.

Ve tam olarak farkın ne olduğunu söylemek için:

  • String.contentEquals()a String, a StringBuilder, a StringBuffer, a CharSequenceve bunların türetilmiş tüm sınıflarının içeriklerini karşılaştırabilir . Parametre String türündeyse, String.equals()çalıştırılır.

  • String.equals()yalnızca String nesnelerini karşılaştırır. Diğer tüm nesne türleri eşit değildir.

  • String.contentEquals()karşılaştırabilir StringBufferve StringBuilderakıllıca olabilir . O mu değil ağır diyoruz toString()ki kopya yeni String nesnesine bütün içeriği yöntemi. Bunun yerine, char[]harika olan temel diziyle karşılaştırır .


33

Bu cevap dbw tarafından zaten gönderilmişti ancak sildi ancak yürütme zamanını karşılaştırırken fark için çok geçerli puanları vardı, hangi istisnaların atıldığını,

String # equals ve String # contentEquals kaynak koduna bakarsanız, String#contentEqualsbiri StringBuilderve diğeri için geçersiz kılınmış iki yöntem olduğu açıktır CharSequence.
Aralarındaki fark,

  1. String#contentEqualssağlanan bağımsız değişkense NPE atacak, nullancak String#equalsdönecekfalse
  2. String#equalsiçeriği sadece sağlanan argüman instance of Stringaksi halde falsediğer tüm durumlarda geri dönecekse karşılaştırır , ancak diğer yandan String#contentEqualsarayüzü uygulayan tüm nesnelerin içeriğini kontrol eder CharSequence.
  3. Ayrıca, aşağıda gösterildiği gibi iletilen argümanın yöntemini String#contentEqualsgeçersiz kılarak, istediğiniz yanlış sonucu veya sonucu döndürmek için kodu equalsince ayar yapabilirsiniz, ancak bu ince ayarları ile yapamazsınız String#equals.
    Aşağıdaki kod her zamantrue 3 karakter uzunluğunda olanı siçerdiği sürece üretecektir .string

        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#contentEqualsString#Equalsbağımsız değişken sağlandığında instance of Stringve her ikisinin uzunluğunun Stringaynı olduğu ancak içeriklerin eşit olmadığı durumda daha yavaş olacaktır .
    Örnek eğer dizge ise String s = "madam"ve String argPassed = "madan"sonra s.contentEquals(argPassed)bu durumda,s.equals(argPassed)

  5. İçerik uzunluğu her iki dizge için aynı değilse, işlev hemen hemen tüm olası durumlarda String#contentEqualsdaha iyi performansa sahip olacaktır String#Equals.

Cevabına eklemek için bir nokta daha var

  1. String#contentEqualsbir Stringnesnenin StringBuilderiçeriği de içerikle karşılaştırılacak ve uygun sonucu sunarken String#Equalsgeri dönecektir.false

4
@dbw bu cevap, gönderdiğiniz cevaptan geliyor
Prateek

@dbw Ayrıca neden gönderinizi sildiniz?
MC Emperor

14
  • Stringsınıf equals(Object o)yöntemi yalnızca Stringkarşılaştırma yapar . Ama contentEquals(CharSequence cs)sınıflar için denetler uzanır AbstractStringBuilderie StringBuffer, StringBuilderve String(Hepsi tiptedir da sınıfını CharSequence).

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

çıktı:

false
true

İlk Stmt çıktısı falseiçin builderdeğil tiptedir String, böylece equals()döner falseama contentEquals()gibi her tür içerik kontrol StringBuilder, StringBuffer, Stringve içerik dolayısıyla aynıdır true.

  • contentEqualsEşittir () , bağımsız değişken ise false döndüren instanceOf ( ) öğesini kontrol ettiğinden, NullPointerExceptionsağlanan bağımsız değişkense nullancak equals()yanlış döndürürse atar .if (anObject instance of String)null

14

contentEquals(CharSequence cs):

  • Arayüzün herhangi uygulama örneği ile verilen dize değeri eşitliğini kontrol Sağlar java.lang.CharacterSequence(örneğin CharBuffer, Segment, String, StringBuffer, StringBuilder)

equals(Object anObject):

  • Yalnızca herhangi bir tür örneğiyle verilen dize değerinin eşitliğini kontrol etmenizi sağlarjava.lang.String

RTFC :)

Kaynağı okumak onu anlamanın en iyi yolu olduğundan, her iki yöntemin uygulamalarını paylaşıyorum (jdk 1.7.0_45 itibariyle)

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;
 }

String # contentEquals () için başka bir yöntem daha vardır:

public boolean contentEquals(StringBuffer sb) {
    synchronized(sb) {
        return contentEquals((CharSequence)sb);
    }
}

9

equals()ve sınıfta iki ve ile karşılaştırmak contentEquals()için iki yöntem vardır .StringstringsstringStringBuffer

Parametreleri contentEquals()vardır StringBufferve String(charSequence). equals()ikisini karşılaştırmak için kullanılır stringsve contentEquals()içeriğini karşılaştırmak için kullanılırString veStringBuffer .

Yöntem contentEqualsve equalsvardır

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

İşte her iki yöntemi de açıklayan bir kod

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);
    }
}

Çıktı:

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

7

Dize # eşittir , Object'i bir argüman olarak alır ve String nesnesi örneği olup olmadığını kontrol eder. Argüman nesnesi String Object ise, içeriği karakter karakter karşılaştırır. Her iki dize nesnesinin içeriğinin aynı olması durumunda true döndürür.

Dize # contentEquals , CharSequence arabirimini bağımsız değişken olarak alır. CharSequence, i) String sınıfı veya (ii) AbstractStringBuilder (StringBuffer'ın ana sınıfı, StringBuilder) kullanılarak 2 şekilde uygulanabilir.

Gelen contentEquals () uzunluğu herhangi bir nesne, örneğin kontrolünden önce karşılaştırılır. Uzunluk aynıysa, argüman nesnesinin AbstractStringBuilder örneği olup olmadığını kontrol eder. Eğer öyleyse (yani StringBuffer veya StringBuilder) içerik karakter karakter kontrol edilir. Argümanın bir String nesnesi olması durumunda, String # eşittir String # contentEquals'dan çağrılır.

Kısacası,

String # equals , argümanın aynı zamanda String nesnesi olması durumunda içerik karakterini karaktere göre karşılaştırır. Ve String # contentEquals , bağımsız değişken nesnesinin CharSequence arabirimini uygulaması durumunda içeriği karşılaştırır.

String # contentEquals, String # contentEquals dahili olarak String nesnesi için String # equals çağırdığında iki aynı uzunlukta string içeriğini karşılaştırdığımızda daha yavaştır.

Farklı içerik uzunluğuna sahip nesneleri karşılaştırmaya çalışırsak ("abc" ile "abcd" diyelim), String # contentEquals, String # equals'dan daha hızlıdır. Çünkü uzunluk, herhangi bir nesne örneği kontrolünden önce karşılaştırılır.


6

contentEquals()Yöntem, kontrol içeriği arasında aynı olduğu String, StringBuffervs, bu karakter dizisinin bir tür.


5

BTW, farkın tarihsel nedeni, String'in başlangıçta üst sınıfının olmamasıdır, bu nedenle String.equals (), argüman olarak bir String alır. CharSequence, String'in üst sınıfı olarak tanıtıldığında, tüm CharSequence uygulamalarında çalışan ve String tarafından halihazırda kullanılmakta olan equals () ile çakışmayan kendi bir eşitlik testine ihtiyaç duyuyordu ... bu yüzden CharSequence.contentEquals ( ), String tarafından miras alınır.

Java 1.0'da CharSequence mevcut olsaydı, olasılıkla yalnızca CharSequence.equals () olurdu ve String bunu basitçe uygulardı.

Ah, gelişen dillerin sevinci ...

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.