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

||
String#equals
方法和
String#contentEquals
方法有什么区别?     
已邀请:
        
String#equals()
不仅比较String的内容,还检查另一个对象是否也是
String
的实例。 “ 4”仅比较内容(字符序列),不检查其他对象是否也是“ 3”的实例。只要是涵盖A.o的
CharSequence
的实现,它就可以是任何东西。
String
StringBuilder
StringBuffer
CharBuffer
等。     
        简单地说:ѭ11是
String.equals()
的聪明兄弟,因为它在实现上比implementation12ѭ更自由。 有某些原因导致使用单独的“ 11”方法。我认为最重要的原因是:
equals
方法必须自反。那意味着:
x.equals(y) == y.equals(x)
。这意味着
aString.equals(aStringBuffer)
必须与as18ѭ相同。这将需要Java API开发人员在StringBuffer,StringBuilder和CharSequence的“ 19”方法中对String进行一些特殊的实现。这将是一团糟。 因此,这就是
String.contentEquals
出现的时候。这是一种独立的方法,不必遵循
Object.equals
的严格要求和规则。这样,您可以更自由地实现“平等内容”的感觉。例如,这使您可以在StringBuffer和String之间进行智能比较。 再说一下到底有什么区别:
String.contentEquals()
可以比较
String
,a8ѭ,a9ѭ,a6ѭ以及它们所有派生类的内容。如果参数的类型为String,则执行
String.equals()
String.equals()
仅比较String对象。所有其他对象类型均视为不相等。
String.contentEquals()
可以智能地比较
StringBuffer
StringBuilder
。它不会调用笨拙的“ 32”方法,该方法会将整个内容复制到新的String对象。相反,它与底层的“ 33”数组进行了比较,这很棒。     
        这个答案已经由dbw发布,但是他删除了,但是在比较执行时间,抛出什么异常, 如果查看源代码String#equals和String#contentEquals,很显然,对于
String#contentEquals
有两种覆盖的方法,其中一种采用
StringBuilder
,而另一些采用
CharSequence
。 他们之间的区别 如果提供的参数为
null
,则
String#contentEquals
将抛出NPE,但
String#equals
将返回
false
String#equals
仅在提供的参数为
instance of String
时比较内容,否则在所有其他情况下将返回
false
,但另一方面
String#contentEquals
检查实现接口
CharSequence
的所有对象的内容。 您还可以调整代码,以使
String#contentEquals
返回错误的结果或想要的结果,方法是重写传递的参数的
equals
方法,如下所示,但不能对
String#equals
进行那些调整。 只要
s
包含任何3个字符长的
string
,下面的代码将始终生成
true
    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;
        }
    }));
如果提供的参数是
instance of String
并且两个
String
的长度相同但内容不相等,则
String#contentEquals
会比
String#Equals
慢。 例如,如果字符串是
String s = \"madam\"
String argPassed = \"madan\"
,那么
s.contentEquals(argPassed)
将比
s.equals(argPassed)
花费几乎两倍的执行时间。 如果两个字符串的内容长度都不相同,则在几乎所有可能的情况下,函数
String#contentEquals
的性能将优于then54。 还有一点要补充
String
对象中的
String#contentEquals
也将与
StringBuilder
的内容进行比较并提供适当的结果,而
String#Equals
将返回
false
    
        
contentEquals(CharSequence cs)
: 让您检查给定字符串值与接口
java.lang.CharacterSequence
的任何实现实例是否相等(例如
CharBuffer
Segment
String
StringBuffer
StringBuilder
equals(Object anObject)
: 可让您仅使用
java.lang.String
类型的任何实例检查给定字符串值的相等性 RTFC :) 由于阅读源代码是理解它的最佳方式,因此我将分享这两种方法的实现(自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;
 }
还有另一个String#contentEquals()方法:
public boolean contentEquals(StringBuffer sb) {
    synchronized(sb) {
        return contentEquals((CharSequence)sb);
    }
}
    
String
equals(Object o)
方法仅进行does3ѭ比较。但是
contentEquals(CharSequence cs)
类的检查扩展了
AbstractStringBuilder
类,即
StringBuffer
StringBuilder
String
类(它们都是
CharSequence
类型)。
String str = \"stackoverflow\";
StringBuilder builder = new StringBuilder(str);
System.out.println(str.equals(builder));
System.out.println(str.contentEquals(builder));
输出:
false
true
first stmt的输出为
false
,因为
builder
不是
String
类型,因此
equals()
返回
false
,但是
contentEquals()
检查所有类型的内容,如
StringBuilder
StringBuffer
String
,并且内容相同,因此为
true
。 如果提供的参数是
null
,则
contentEquals
将抛出
NullPointerException
,但equal19ѭ将返回false,因为equals()检查instanceOf(
if (anObject instance of String)
),如果参数是
null
,则返回false。     
        
equals()
contentEquals()
String
类中的两种方法,用于将两个
strings
string
StringBuffer
进行比较。
contentEquals()
的参数为
StringBuffer
String(charSequence)
equals()
用于比较两个
strings
contentEquals()
用于比较
String
StringBuffer
的内容。 方法
contentEquals
equals
public boolean contentEquals(java.lang.StringBuffer);
public boolean contentEquals(java.lang.CharSequence);
public boolean equals(Object o)
这是描述两种方法的代码
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);
    }
}
输出:
 str1.equals(str2) - true
 str1.equals(sb1) - false
 str1.contentEquals(sb1) - true
 str1.contentEquals(sb2) - false
 str1.contentEquals(str2) - true
    
        
contentEquals()
方法检查的是are3ѭ,
StringBuffer
等某种字符序列的内容是否相同。     
        String#equals将Object作为参数,并检查其是否为String对象的实例。如果参数对象是字符串对象,则它将逐字符比较内容。如果两个字符串对象的内容相同,则返回true。 String#contentEquals将CharSequence接口作为参数。 CharSequence可以通过两种方式实现-通过使用i)字符串类或(ii)AbstractStringBuilder(StringBuffer,StringBuilder的父类) 在contentEquals()中,将在检查任何对象实例之前比较长度。如果长度相同,则检查参数对象是否为AbstractStringBuilder的实例。如果是这样(即StringBuffer或StringBuilder),则逐字符检查内容。如果参数是String对象的实例,则从String#contentEquals调用String#equals。 简而言之, 如果参数也是String对象,则String#equals逐字符比较内容。如果参数对象实现CharSequence接口,则String#contentEquals比较内容。 万一我们比较两个相同长度的字符串内容,因为String#contentEquals内部调用String#equals作为String对象,则String#contentEquals速度会变慢。 如果我们尝试比较内容长度不同的对象(例如\“ abc \”与\“ abcd \”),则String#contentEquals比String#equals更快。因为长度是在任何对象实例检查之前进行比较的。     
        顺便说一句,造成这种差异的历史原因是String最初没有超类,因此String.equals()将String作为其参数。当CharSequence作为String的超类引入时,它需要自己的一个相等性测试,该测试适用于所有CharSequence实现,并且不会与String已经使用的equals()相冲突...因此我们得到了CharSequence.contentEquals( ),由String继承。 如果Java 1.0中已经存在CharSequence,那么我们可能只具有CharSequence.equals()而String会简单地实现它。 啊,不断发展的语言所带来的乐趣...     

要回复问题请先登录注册