如何解决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会简单地实现它。
啊,不断发展的语言所带来的乐趣...
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。