String#equals方法和String#contentEquals方法之间有什么区别?
String#equals方法和String#contentEquals方法之间有什么区别?
Answers:
该String#equals()不是只有在其他对象也是一个实例比较字符串的内容,而且检查String。在String#contentEquals()只比较的内容(字符序列)和不不检查其他对象也是的一个实例String。它可以是任何东西,只要它是一个实现CharSequence覆盖AO String,StringBuilder,StringBuffer,CharBuffer,等。
==运算符将只允许您比较引用而不是两个对象的内容。
==提到的只是JavaScript;关于Java从来没有提到过。
==在JavaScript远高于宽松contentEquals,这不会触及数,例如),但你即将正确equals的确切类型匹配检查与Strings(其他类可能是他们的宽松有型equals的方法) 。
轻松地说:String.contentEquals()是的更聪明的兄弟String.equals(),因为它在实现中比可以更加自由String.equals()。
有某些原因导致使用单独的String.contentEquals()方法。我认为最重要的原因是:
equals方法必须是自反的。这意味着:x.equals(y) == y.equals(x)。这意味着aString.equals(aStringBuffer)必须与相同aStringBuffer.equals(aString)。这将要求Java API开发人员也使用equals()StringBuffer,StringBuilder和CharSequence方法对String进行一些特殊的实现。这将是一团糟。这就是String.contentEquals进来,这是一个独立的方法,它没有必须遵循严格的要求和规则的Object.equals。这样,您可以更自由地实现“平等内容”的感觉。例如,这使您可以在StringBuffer和String之间进行智能比较。
再说一下到底有什么区别:
String.contentEquals()可以比较a String,a StringBuilder,a StringBuffer,a CharSequence和所有这些派生类的内容。如果参数的类型为String,则String.equals()执行该参数。
String.equals()仅比较String对象。所有其他对象类型均视为不相等。
String.contentEquals()可以比较StringBuffer并StringBuilder以一种智能的方式进行比较。它不叫重toString()方法,其拷贝的全部内容到一个新的String对象。相反,它将与基础char[]数组进行比较,这很棒。
这个答案已经由dbw发布,但是他删除了,但是在比较执行时间,抛出什么异常,
如果您查看源代码String#equals和String#contentEquals,很明显,对于String#contentEquals一个方法take StringBuilder和另一个,有两种覆盖的方法CharSequence。
他们之间的区别,
String#contentEquals如果提供的参数为,将抛出NPE,null但String#equals返回falseString#equals仅在提供的参数instance of String否则比较内容,否则false在所有其他情况下它都会返回,但另一方面String#contentEquals检查实现接口的所有对象的内容CharSequence。您还可以调整代码,以便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;
}
}));String#contentEquals则String#Equals在提供的参数为instance of String且两者的长度String相同但内容不相等的情况下会慢一些。
例如,如果字符串为String s = "madam"and,String argPassed = "madan"那么s.contentEquals(argPassed)在这种情况下,与之相比,将花费几乎两倍的执行时间s.equals(argPassed)
如果两个字符串的内容长度都不相同,则函数String#contentEquals将String#Equals在几乎所有可能的情况下具有更好的性能。
还有一点要补充
String#contentEquals一个的String对象也将比较的StringBuilder内容,同时提供相应的结果String#Equals将返回false String类equals(Object o)方法仅做String比较。但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。
contentEqualsNullPointerException如果提供的参数为,则会抛出该错误,null但equals()将返回false,因为equals()检查instanceOf(if (anObject instance of String)),如果参数为,则返回false null。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);
}
}
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
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会简单地实现它。
啊,不断发展的语言所带来的乐趣...
==(contentEquals)和===(equals)吗?