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

时间:2011-06-25 07:54:31

标签: java string equality

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

9 个答案:

答案 0 :(得分:135)

String#equals()不仅会比较字符串的内容,还会检查另一个对象是否也是String的实例。 String#contentEquals()仅比较内容(字符序列),并且检查另一个对象是否也是String的实例。它可以是任何东西,只要它是CharSequence的实现,它涵盖了a.o. StringStringBuilderStringBufferCharBuffer等。

答案 1 :(得分:33)

轻松一点: String.contentEquals()String.equals()的聪明兄弟,因为它在实施中比String.equals()更加自由。

有一些原因可以解释为什么有单独的String.contentEquals()方法。我认为最重要的原因是:

  • equals方法必须是自反的。这意味着:x.equals(y) == y.equals(x)。这意味着aString.equals(aStringBuffer)必须与aStringBuffer.equals(aString)相同。这需要Java API开发人员在StringBuffer,StringBuilder和CharSequence的equals()方法中为Strings做一些特殊的实现。这将是一团糟。

所以,那就是String.contentEquals进来的时候。这是独立方法必须遵循严格的要求和规则 Object.equals。这样,您就可以更自由地实现“equal content”的意义。这允许您在StringBuffer和String之间进行智能比较,例如。

并说明究竟有什么区别:

  • String.contentEquals()可以比较StringStringBuilderStringBufferCharSequence及其所有派生类的内容。如果参数的类型为String,则String.equals()将被执行。

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

  • String.contentEquals()可以智能方式比较StringBufferStringBuilder。它调用繁重的toString()方法,该方法将整个内容复制到新的String对象。相反,它与底层的char[]数组进行比较,这很好。

答案 2 :(得分:28)

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

如果您查看源代码String#equalsString#contentEquals,很明显String#contentEquals有两个被覆盖的方法,其中包含StringBuilder和其他CharSequence }。
他们之间的区别,

    如果提供的参数为String#contentEqualsnull将返回String#equals ,则
  1. false将抛出NPE
  2. String#equals仅在提供的参数为instance of String时比较内容,否则在所有其他情况下将返回false但另一方面String#contentEquals检查所有内容实现接口CharSequence
  3. 的对象
  4. 您还可以调整代码,以便String#contentEquals通过覆盖如下所示传递的参数的equals方法返回您想要的错误结果或结果,但是您无法执行这些调整String#equals
    只要true包含任意长度为3个字符的s,代码就会始终生成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;
            }
        }));
    
  5. 在提供的参数为String#contentEquals并且String#Equals的长度相同但内容不相等的情况下,
  6. instance of String将慢于String
    示例如果字符串为String s = "madam"String argPassed = "madan"s.contentEquals(argPassed)s.equals(argPassed)

    相比,在这种情况下,执行时间几乎会缩短一倍
  7. 如果两个字符串的内容长度不同,那么在几乎所有情况下,函数String#contentEquals的性能都会比String#Equals更好。

  8. 还有一点要加上他的回答

      {li} String#contentEquals对象的{li> String也将与StringBuilder内容进行比较,并在String#Equals将返回false 时提供相应的结果

答案 3 :(得分:13)

<强> contentEquals(CharSequence cs)

  • 允许您检查给定字符串值与接口java.lang.CharacterSequence的任何实现实例的相等性(例如,CharBufferSegmentStringStringBuffer,{ {1}})

<强> StringBuilder

  • 允许您检查给定字符串值与任何类型equals(Object anObject)
  • 的实例的相等性

RTFC:)

由于阅读源代码是理解它的最佳方式,因此我将分享这两种方法的实现(从jdk 1.7.0_45开始)

java.lang.String

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

还有另一种String#contentEquals()方法:

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

答案 4 :(得分:10)

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

<强>输出:

false
true

第一个stmt的输出为false,因为builder不是String类型,因此equals()返回false,但contentEquals()检查所有类型的内容,例如StringBuilderStringBufferString,因为内容相同,因此true

    如果提供的参数为contentEquals,则
  • NullPointerException将抛出null,但equals()将返回false,因为equals()检查instanceOf( {{1} } )如果参数为if (anObject instance of String),则返回false。

答案 5 :(得分:8)

equals()contentEquals()String课程中的两种方法,可将两个stringsstringStringBuffer进行比较。

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

方法contentEqualsequals

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

答案 6 :(得分:6)

contentEquals()方法检查是StringStringBuffer等内容在某种char序列之间是相同的。

答案 7 :(得分:6)

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

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

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

调用

简而言之,

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

String#contentEquals比较慢,以防我们比较两个相同长度的字符串内容,因为String#contentEquals内部调用String#equals for String object。

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

答案 8 :(得分:5)

BTW,差异的历史原因是String最初没有超类,因此String.equals()将String作为其参数。当CharSequence作为String的超类引入时,它需要一个自己的相等测试,它在所有CharSequence实现中都有效,并且不会与已经被String使用的equals()发生碰撞......所以我们得到了CharSequence.contentEquals( ),由String继承。

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

啊,不断发展的语言的乐趣......