String类中进行比较有equals(),contentEquals()。
equals的源码
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;
}
先对传进来的对象进行地址比较,再依次比较字符串中的字符。
contentEquals()
public boolean contentEquals(StringBuffer sb) {
return contentEquals((CharSequence)sb);
}
public boolean contentEquals(CharSequence cs) {
// Argument is a StringBuffer, StringBuilder
if (cs instanceof AbstractStringBuilder) {
if (cs instanceof StringBuffer) {
synchronized(cs) {
return nonSyncContentEquals((AbstractStringBuilder)cs);
}
} else {
return nonSyncContentEquals((AbstractStringBuilder)cs);
}
}
// Argument is a String
if (cs instanceof String) {
return equals(cs);
}
// Argument is a generic CharSequence
char v1[] = value;
int n = v1.length;
if (n != cs.length()) {
return false;
}
for (int i = 0; i < n; i++) {
if (v1[i] != cs.charAt(i)) {
return false;
}
}
return true;
}
private boolean nonSyncContentEquals(AbstractStringBuilder sb) {
char v1[] = value;
char v2[] = sb.getValue();
int n = v1.length;
if (n != sb.length()) {
return false;
}
for (int i = 0; i < n; i++) {
if (v1[i] != v2[i]) {
return false;
}
}
return true;
}
如果要比较的对象不知道是否是String类的实例,则使用contentEquals()进行比较,如果是StringBuffer则将其转换成CharSequence。
因为StringBuffer和StringBuilder都是AbstractStringBuilder的子类所以使用
cs instanceof AbstractStringBuilder 与cs instanceof String来将cs分为AbstractStringBuilder,String,char[]。
对于AbstractStringBuilder进行判断cs是线程安全的StringBuffer还是非线程安全的StringBuilder。
如果是StringBuffer则在判断前通过synchronized对其进行加锁然后使用nonSyncContentEquals()
进行进一步处理,否则直接使用nonSyncContentEquals()处理。
nonSyncContentEquals()原理与String中equals一样。
对于String则调用equals进行判断
对于char[]则使用循环判断v1[i] != cs.charAt(i),也是进行内容的比较。
String类的equals()只能对String对象进行比较,对其他类型的字符串数据应采用contentEquals()。