Java源码阅读之String(3)
这一篇博客主要读一下String类的比较方法
/**
*将anotherString对象和当前对象进行对比,对比方式为
*从两者首位依次向后对比,知道对比到其中一个结束
*返回值为负数则当前对象小,返回0则相等,返回正数则当前对象大
*/
public int compareTo(String anotherString) {
int len1 = value.length;
int len2 = anotherString.value.length;
int lim = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value;
int k = 0;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
return len1 - len2;
}
//CaseInsensitiveComparator内部类是实例化Comparator接口的一个类
//用于实现忽略字母大小写的字符串对比
public static final Comparator<String> CASE_INSENSITIVE_ORDER
= new CaseInsensitiveComparator();
private static class CaseInsensitiveComparator
implements Comparator<String>, java.io.Serializable {
// use serialVersionUID from JDK 1.2.2 for interoperability
private static final long serialVersionUID = 8575799808933029326L;
public int compare(String s1, String s2) {
int n1 = s1.length();
int n2 = s2.length();
int min = Math.min(n1, n2);
for (int i = 0; i < min; i++) {
char c1 = s1.charAt(i);
char c2 = s2.charAt(i);
if (c1 != c2) {
c1 = Character.toUpperCase(c1);
c2 = Character.toUpperCase(c2);
if (c1 != c2) {
c1 = Character.toLowerCase(c1);
c2 = Character.toLowerCase(c2);
if (c1 != c2) {
// No overflow because of numeric promotion
return c1 - c2;
}
}
}
}
return n1 - n2;
}
//替换反序列化的对象
private Object readResolve() { return CASE_INSENSITIVE_ORDER; }
}
//忽略字母大小写比较当前对象和str对象的大小
public int compareToIgnoreCase(String str) {
调用内部类CASE_INSENSITIVE_ORDER的compare方法
return CASE_INSENSITIVE_ORDER.compare(this, str);
}
/**
*对比当前对象和other对象的子串是否相等可以指定两者开始位置和长度
*toffset指定当前对象对比的开始位置,ooffset指定other对象开始对比的位置
*len指定两者对比的长度
*/
public boolean regionMatches(int toffset, String other, int ooffset, int len) {
char ta[] = value;
int to = toffset;
char pa[] = other.value;
int po = ooffset;
//检查ooffset和toffset是否合法(是否小于0,是否能够支持len长度的子串)
if ((ooffset < 0) || (toffset < 0) || (toffset > (long)value.length - len)
|| (ooffset > (long)other.value.length - len)) {
return false;
}
//长度自减和两者偏移量自增
while (len-- > 0) {
if (ta[to++] != pa[po++]) {
return false;
}
}
return true;
}
/**
*忽略字母大小写的方式对比当前对象和other对象的子串是否相等可以指定两者开始位置和长度
*toffset指定当前对象对比的开始位置,ooffset指定other对象开始对比的位置
*len指定两者对比的长度,ignoreCase是否忽略字母大小写
*/
public boolean regionMatches(boolean ignoreCase, int toffset,
String other, int ooffset, int len) {
char ta[] = value;
int to = toffset;
char pa[] = other.value;
int po = ooffset;
//检查ooffset和toffset是否合法(是否小于0,是否能够支持len长度的子串)
if ((ooffset < 0) || (toffset < 0)|| (toffset > (long)value.length - len)
|| (ooffset > (long)other.value.length - len)) {
return false;
}
//长度自减和两者偏移量自增
while (len-- > 0) {
char c1 = ta[to++];
char c2 = pa[po++];
if (c1 == c2) {
continue;
}
//如果ignoreCase为true,将两者都转为大写字母和小写字母进行对比
if (ignoreCase) {
char u1 = Character.toUpperCase(c1);
char u2 = Character.toUpperCase(c2);
if (u1 == u2) {
continue;
}
if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) {
continue;
}
}
return false;
}
return true;
}
//判断当前对象是否从toffset位置以prefix开始(当toffset=0即是否以prefix开头)
public boolean startsWith(String prefix, int toffset) {
char ta[] = value;
int to = toffset;
char pa[] = prefix.value;
int po = 0;
int pc = prefix.value.length;
//判断偏移量toffset是否合法
if ((toffset < 0) || (toffset > value.length - pc)) {
return false;
}
while (--pc >= 0) {
if (ta[to++] != pa[po++]) {
return false;
}
}
return true;
}
//判断当前对象是否以prefix开头
public boolean startsWith(String prefix) {
return startsWith(prefix, 0);
}
//判断当前对象是否以prefix结束
public boolean endsWith(String suffix) {
return startsWith(suffix, value.length - suffix.value.length);
}
这些就是String类的对比方法,注释的不完全,如果感兴趣可以参阅源码。