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
返回false
String#equals
仅在提供的参数instance of String
否则比较内容,否则false
在所有其他情况下它都会返回,但另一方面String#contentEquals
检查实现接口的所有对象的内容CharSequence
。您还可以调整代码,以便String#contentEquals
通过覆盖equals
传递的参数的方法来返回错误的结果或所需的结果,如下所示,但是您不能使用进行这些调整String#equals
。只要包含3个字符长的
代码,下面的代码将始终产生true
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;
}
}));
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
。
contentEquals
NullPointerException
如果提供的参数为,则会抛出该错误,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)吗?