Java String#equals 和 String#contentEquals 方法之间的区别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6476600/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 06:15:51  来源:igfitidea点击:

Difference between String#equals and String#contentEquals methods

javastringequality

提问by Arathana

What is the difference between the String#equalsmethod and the String#contentEqualsmethod?

String#equals方法和String#contentEquals方法有什么区别?

回答by BalusC

The String#equals()not only compares the String's contents, but also checks if the other object is also an instance of a String. The String#contentEquals()only compares the contents (the character sequence) and does notcheck if the other object is also an instance of String. It can be anything as long as it is an implementation of CharSequencewhich covers a.o. String, StringBuilder, StringBuffer, CharBuffer, etc.

String#equals()不是只有在其他对象也是一个实例比较字符串的内容,而且检查String。在String#contentEquals()只比较的内容(字符序列)和不检查其他对象也是的一个实例String。它可以是任何东西,只要它是一个实现CharSequence覆盖AO StringStringBuilderStringBufferCharBuffer,等。

回答by fastcodejava

The contentEquals()method checks is the contents are same between a String, StringBuffer, etc which some kind of char sequence.

contentEquals()方法检查是内容是相同的之间StringStringBuffer等等,其某种字符序列。

回答by Amit Sharma

contentEquals(CharSequence cs):

contentEquals(CharSequence cs)

  • Lets you check equality of given string value with any implementation instance of interface java.lang.CharacterSequence(eg, CharBuffer, Segment, String, StringBuffer, StringBuilder)
  • 允许您检查给定字符串值与接口的任何实现实例的相等性java.lang.CharacterSequence(例如,CharBuffer, Segment, String, StringBuffer, StringBuilder

equals(Object anObject):

equals(Object anObject)

  • Lets you check equality of given string value with any instance of type java.lang.Stringonly
  • 让你检查给出的字符串值的平等类型的任何实例java.lang.String

RTFC :)

RTFC :)

Since reading the source is the best way to understand it, I am sharing the implementations of both the methods (as of jdk 1.7.0_45)

由于阅读源代码是理解它的最佳方式,因此我将分享这两种方法的实现(从 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;
 }


There is another method of String#contentEquals():

String#contentEquals() 还有一个方法:

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

回答by Trying

  • Stringclass equals(Object o)method does only Stringcomparison. But contentEquals(CharSequence cs)checks for classes extends AbstractStringBuilderi.e. StringBuffer, StringBuilderand Stringclass also (They all are of type CharSequence).

    String str = "stackoverflow";
    StringBuilder builder = new StringBuilder(str);
    System.out.println(str.equals(builder));
    System.out.println(str.contentEquals(builder));
    
  • Stringequals(Object o)方法只做String比较。但contentEquals(CharSequence cs)上课的检查延伸AbstractStringBuilder,即 StringBufferStringBuilderString类也(他们都是类型CharSequence)。

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

output:

输出:

false
true

The output of first stmt is falsebecause builderis not of type Stringso equals()returns falsebut the contentEquals()checks for the content of all the type like StringBuilder, StringBuffer, Stringand as the content is same hence true.

第一stmt的输出是false因为builder不是类型的String,以便equals()返回false,但contentEquals()对于所有的种类等的内容检查StringBuilderStringBufferString和作为内容是相同的,因此true

  • contentEqualswill throw NullPointerExceptionif the argument supplied is nullbut equals()will return false because the equals() checks for instanceOf ( if (anObject instance of String)) which returns false if the argument is null.
  • contentEqualsNullPointerException如果提供的参数是,则会抛出nullequals()将返回 false 因为 equals() 检查 instanceOf ( if (anObject instance of String)) 如果参数是 ,则返回 false null

回答by Asfab

equals()and contentEquals()are two methods in Stringclass to compare two stringsand stringwith StringBuffer.

equals()contentEquals()两种方法在String类比较两个stringsstringStringBuffer

The parameters of contentEquals()are StringBufferand String(charSequence). equals()is used to compare two stringsand contentEquals()is used to compare the contents of Stringand StringBuffer.

的参数contentEquals()StringBufferString(charSequence)equals()用于比较两个stringscontentEquals()用于比较的内容StringStringBuffer

Method contentEqualsand equalsare

方法contentEqualsequals

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

Here is an code which describes both methods

这是描述这两种方法的代码

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

Output:

输出:

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

回答by Martijn Courteaux

To put it easily: String.contentEquals()is the smarter brother of String.equals(), because it can be more free in the implementation than String.equals().

简单来说:String.contentEquals()是 的聪明兄弟String.equals(),因为它在实现上可以比String.equals().

There are some reasons why there is a separate String.contentEquals()method. The most important reason I think is:

有一个单独的String.contentEquals()方法有一些原因。我认为最重要的原因是:

  • The equalsmethod has to be reflexive. That means that: x.equals(y) == y.equals(x). This implies that aString.equals(aStringBuffer)would have to be the same as aStringBuffer.equals(aString). This would require the Java API developers to make some special implementation for Strings in the equals()method of StringBuffer, StringBuilder and CharSequence as well. This would be a mess.
  • equals方法必须是自反的。这意味着:x.equals(y) == y.equals(x)。这意味着aString.equals(aStringBuffer)必须与 相同aStringBuffer.equals(aString)。这将需要 Java API 开发人员在equals()StringBuffer、StringBuilder 和 CharSequence 方法中对字符串进行一些特殊实现。这将是一团糟。

So, and that is when String.contentEqualscomes in. This is a standalone methodthat does nothave to follow the strict requirements and rulesfor Object.equals. This way, you can implement the sense of "equal content"more freely. This allows you to make intelligent comparisons between a StringBuffer and a String, for example.

所以,那就是当String.contentEquals进来,这是一个独立的方法,它没有必须遵循严格的要求和规则Object.equals。这样,你就可以更自由地实现“内容平等”的感觉。例如,这允许您在 StringBuffer 和 String 之间进行智能比较。

And to say what exactly the difference is:

并说到底有什么区别:

  • String.contentEquals()can compare the contents of a String, a StringBuilder, a StringBuffer, a CharSequenceand all derivate classes of these. If the parameter is of type String, then String.equals()get executed.

  • String.equals()only compares String objects. All other object types are considered as not equal.

  • String.contentEquals()can compare StringBufferand StringBuilderin an intelligent way. It does notcall the heavy toString()method, which copies the whole content to a new String object. Instead, it compares with the underlying char[]array, which is great.

  • String.contentEquals()可以比较 a String、 a StringBuilder、 a StringBuffer、 a 的内容CharSequence以及它们的所有派生类。如果参数是字符串类型,则String.equals()执行。

  • String.equals()只比较 String 对象。所有其他对象类型都被视为不相等。

  • String.contentEquals()可以比较StringBufferStringBuilder以智能方式。它叫重toString()方法,其拷贝的全部内容到一个新的String对象。相反,它与底层char[]数组进行比较,这很棒。

回答by Prateek

This answer was already posted by dbwbut he deleted it but he had some very valid points for the difference while comparing execution time, what exceptions are thrown,

这个答案已经由dbw发布,但他删除了它,但在比较执行时间、抛出的异常时,他有一些非常有效的差异点,

If you look at the source code String#equalsand String#contentEqualsit is clear that there are two overridden methods for String#contentEqualsone which take StringBuilderand other CharSequence.
The difference between them,

如果您查看源代码String#equalsString#contentEquals,很明显有两个覆盖方法,String#contentEquals一个是 take StringBuilder,另一个是CharSequence
他们之间的区别,

  1. String#contentEqualswill throw NPE if the argument supplied is nullbut String#equalswill return false
  2. String#equalscompares the content only when the argument supplied is instance of Stringotherwise it will return falsein all other cases but on the other hand String#contentEqualschecks the content of all the objects which implement interface CharSequence.
  3. You can also tweak the code so that String#contentEqualsreturn the wrong result or result you want by overriding equalsmethod of the argument passed as shown below but you can not do those tweaks with String#equals.
    Below code will always produce trueas long as scontains any stringwhich is 3 character long

        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#contentEqualswill be slower then String#Equalsin the case when argument supplied is instance of Stringand the length of both Stringis same but contents are not equal.
    Exampleif the string are String s = "madam"and String argPassed = "madan"then s.contentEquals(argPassed)will take almost double execution time in this case as compared to s.equals(argPassed)

  5. If the content length are not same for both the strings then function String#contentEqualswill have better performance then String#Equalsin almost all possible cases.

  1. String#contentEquals如果提供的参数是,则会抛出 NPEnullString#equals会返回false
  2. String#equals仅当提供的参数为时才比较内容,instance of String否则它将false在所有其他情况下返回,但另一方面String#contentEquals检查实现 interface 的所有对象的内容CharSequence
  3. 您还可以String#contentEquals通过覆盖equals传递的参数的方法来调整代码,以便返回错误的结果或您想要的结果,如下所示,但您不能使用String#equals. 只要包含任何长度为3 个字符的
    代码,下面的代码就会始终生成truesstring

        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#Equals在提供的参数是instance of String并且两者的长度String相同但内容不相等的情况下会更慢。
    例如,如果该字符串是String s = "madam"String argPassed = "madan"然后s.contentEquals(argPassed)将相比于需要将近两倍的执行时间在此情况下s.equals(argPassed)

  5. 如果两个字符串的内容长度不同,String#contentEquals那么String#Equals在几乎所有可能的情况下,函数将具有更好的性能。

One more point to add to his answer

还有一点要添加到他的答案中

  1. String#contentEqualsof a Stringobject will also compare to the StringBuildercontents and provide the appropriate result while String#Equalswill return false
  1. String#contentEquals一个的String对象也将比较的StringBuilder内容,同时提供相应的结果String#Equals将返回false

回答by keshlam

BTW, the historical reason for the difference is that String originally had no superclass, so String.equals() takes a String as its argument. When CharSequence was introduced as the superclass of String, it needed an equality test of its own that worked across all CharSequence implementations, and that would not collide with the equals() already in use by String... so we got CharSequence.contentEquals(), which is inherited by String.

顺便说一句,这种差异的历史原因是 String 最初没有超类,所以 String.equals() 将 String 作为其参数。当 CharSequence 作为 String 的超类被引入时,它需要一个自己的相等测试,它适用于所有 CharSequence 实现,并且不会与 String 已经使用的 equals() 冲突......所以我们得到了 CharSequence.contentEquals( ),由String继承。

If CharSequence has been present in Java 1.0, we would probalby have only CharSequence.equals() and String would simply implement that.

如果 Java 1.0 中已经存在 CharSequence,我们可能只有 CharSequence.equals() 而 String 会简单地实现它。

Ah, the joys of evolving languages...

啊,进化语言的乐趣......

回答by Anirban Pal

String#equalstakes Object as an argument and checks it is instance of String object or not. If the argument object is String Object then it compares content character by character. It returns true in case content of both string objects are same.

String#equals将 Object 作为参数并检查它是否是 String 对象的实例。如果参数对象是字符串对象,则它会逐个字符地比较内容。如果两个字符串对象的内容相同,则返回 true。

String#contentEqualstakes CharSequence interface as an argument. CharSequence can be implements in 2 ways-by using i) String class or (ii) AbstractStringBuilder( parent class of StringBuffer, StringBuilder)

String#contentEquals将 CharSequence 接口作为参数。CharSequence 可以通过两种方式实现 - 通过使用 i)String 类或(ii)AbstractStringBuilder(StringBuffer 的父类,StringBuilder)

In contentEquals()length is compared before any object instance check. If length is same then it checks argument object is instance of AbstractStringBuilder or not. If it is so(i.e. StringBuffer or StringBuilder ) then content is checked character by character. In case argument is an instance of String object then String#equals called from String#contentEquals.

contentEquals() 中,在任何对象实例检查之前比较长度。如果长度相同,则它检查参数对象是否是 AbstractStringBuilder 的实例。如果是这样(即 StringBuffer 或 StringBuilder ),则逐个字符检查内容。如果参数是 String 对象的实例,则从 String#contentEquals 调用 String#equals。

So in short,

所以简而言之,

String#equalscompares the content character by character in case argument is String object also. And String#contentEqualscompares the content in case argument object implement CharSequence interface.

String#equals在参数也是 String 对象的情况下逐个字符地比较内容。并且String#contentEquals比较内容,以防参数对象实现 CharSequence 接口。

String#contentEquals is slower in case we compare two same length string content as String#contentEquals internally calls String#equals for String object.

如果我们比较两个相同长度的字符串内容,String#contentEquals 会较慢,因为 String#contentEquals 在内部为 String 对象调用 String#equals。

In case we try to compare objects with difference content length (say "abc" with "abcd") then String#contentEquals is faster than String#equals. Because length is compared before any object instance checking.

如果我们尝试比较具有不同内容长度的对象(比如“abc”和“abcd”),那么 String#contentEquals 比 String#equals 快。因为在任何对象实例检查之前比较长度。