1.String的compareTo方法源码:
java中的compareto方法,返回参与比较的前后两个字符串的asc码的差值,看下面一组代码
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;
//从第一个位置开始到长度的最小长度比较两个数组中的字符串ASC码大小
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
//如果不相等就返回从左到右字符串的相同位置不同字符的asc码差值。
return c1 - c2;
}
k++;
}
//如果两个字符串最小长度前面的字符都同等,返回两个字符串的差值
return len1 - len2;
}
案例:
2.String的valueOf方法源码:
JDK提供了其他基本类型转换为String类型的方法valueOf的很多重载方法,如下图:
其底层实现方式都是对类型进行了重新的封装
public static String valueOf(char c) {
char data[] = {c};
return new String(data, true);
}
//通过构造方法将其封装为新的String类型
String(char[] value, boolean share) {
// assert share : "unshared not supported";
this.value = value;
}
3.String的indexOf方法源码:
JDK提供了indexOf的很多重载方法,如下图:
其实indexOf的重载方法的实现都是相互调用的;例如:
(1)对于判断以X字符的ASC码为开始位置的indexOf的实现
public int indexOf(int ch) {
//默认开始位置为0
return indexOf(ch, 0);
}
public int indexOf(int ch, int fromIndex) {
final int max = value.length;
//如果开始位置小于0,则默认为0
if (fromIndex < 0) {
fromIndex = 0;
//如果开始位置大于源字符串长度,返回-1
} else if (fromIndex >= max) {
// Note: fromIndex might be near -1>>>1.
return -1;
}
//增补代码点的最小值Character.MIN_SUPPLEMENTARY_CODE_POINT = 0x010000;
if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
// handle most cases here (ch is a BMP code point or a
// negative value (invalid code point))
final char[] value = this.value;
//循环比较是否有字符的ASC码和它一致,如果一直就返回
for (int i = fromIndex; i < max; i++) {
if (value[i] == ch) {
return i;
}
}
return -1;
} else {
//否则通过另一条线进行判断
return indexOfSupplementary(ch, fromIndex);
}
}
private int indexOfSupplementary(int ch, int fromIndex) {
if (Character.isValidCodePoint(ch)) {
final char[] value = this.value;
final char hi = Character.highSurrogate(ch);
final char lo = Character.lowSurrogate(ch);
final int max = value.length - 1;
for (int i = fromIndex; i < max; i++) {
if (value[i] == hi && value[i + 1] == lo) {
return i;
}
}
}
return -1;
}
高代理的算法是这样的:
public static char highSurrogate(int codePoint) {
return (char) ((codePoint >>> 10)
+ (MIN_HIGH_SURROGATE - (MIN_SUPPLEMENTARY_CODE_POINT >>> 10)));
}
高代理是将参数codePoint右移10位,加上D800这个字符减去65536右移16位之后所得数的差,然后强转为char类型
低代理的算法是
public static char lowSurrogate(int codePoint) {
return (char) ((codePoint & 0x3ff) + MIN_LOW_SURROGATE);
}
低代理是将参数与1023进行按位运算,就是将两个数转换成二进制,每一位进行比较,如果两个数的对应数位上有一个是0,那么结果对应数位就是0,最后得到的结果转换成十进制,然后再加上DC00这个字符,得到的结果进行强转为char
public static boolean isValidCodePoint(int codePoint) {
// Optimized form of:
// codePoint >= MIN_CODE_POINT && codePoint <= MAX_CODE_POINT
int plane = codePoint >>> 16;
return plane < ((MAX_CODE_POINT + 1) >>> 16);
}
(2)对于判断以X字符为开始位置的indexOf的实现
public int indexOf(String str) {
//默认从零位置开始
return indexOf(str, 0);
}
public int indexOf(String str, int fromIndex) {
return indexOf(value, 0, value.length,
str.value, 0, str.value.length, fromIndex);
}
最终调用的是static静态方法:
//参数分别为:源字符数组、源偏移量、源字符串长度、目标字符数组、目标偏移量、目标字符数组长度、开始位置
static int indexOf(char[] source, int sourceOffset, int sourceCount,char[] target, int targetOffset, int targetCount,int fromIndex) {
//判断开始位置是否大于等于源字符串长度
if (fromIndex >= sourceCount) {
//如果目标字符数组长度为0,即“”,返回的是源字符串长度;否则,返回为-1
return (targetCount == 0 ? sourceCount : -1);
// System.out.println("abcd".indexOf("",5)); //4
}
//如果开始位置小于0,进行初始化为0
if (fromIndex < 0) {
fromIndex = 0;
}
//如果目标字符串长度为0时,直接返回开始位置的值,例如“”
if (targetCount == 0) {
return fromIndex;
}
//获取目标字符串的首个字符
char first = target[targetOffset];
//计算需要比较到值
int max = sourceOffset + (sourceCount - targetCount);
//从开始比较位置开始进行一个一个比较;(目标字符串的第一个位置和源字符串进行一个一个比较)
for (int i = sourceOffset + fromIndex; i <= max; i++) {
/* Look for first character. */
//首先来lock第一个字符相同的位置
if (source[i] != first) {
while (++i <= max && source[i] != first);
}
/* Found first character, now look at the rest of v2 */
if (i <= max) {
//从第一个字符相同锁定位置开始进行往后比较,比较到目标字符最后一个
int j = i + 1;
int end = j + targetCount - 1;
//(源字符串和目标字符串锁定位置开始一一字符比较)
for (int k = targetOffset + 1; j < end && source[j] == target[k]; j++, k++);
//如果最后字符各个位置都相同,时当j==end(最后一个);这样就保证了目标字符串被包含
if (j == end) {
/* Found whole string. */
//返回第一次重叠的位置;锁定第一字符相同的位置减去源字符的偏移量,一遍偏移量为0
return i - sourceOffset;
}
}
}
return -1;
}
4.String中lastIndexOf的方法源码:
由于lastIndexOf和indexOf的返回目的完全相反,这样其实现逻辑也大致相同在这我就只把源码进行粘贴供大家了解:
(1)
public int lastIndexOf(int ch) {
return lastIndexOf(ch, value.length - 1);
}
public int lastIndexOf(int ch, int fromIndex) {
if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
// handle most cases here (ch is a BMP code point or a
// negative value (invalid code point))
final char[] value = this.value;
int i = Math.min(fromIndex, value.length - 1);
for (; i >= 0; i--) {
if (value[i] == ch) {
return i;
}
}
return -1;
} else {
return lastIndexOfSupplementary(ch, fromIndex);
}
}
private int lastIndexOfSupplementary(int ch, int fromIndex) {
if (Character.isValidCodePoint(ch)) {
final char[] value = this.value;
char hi = Character.highSurrogate(ch);
char lo = Character.lowSurrogate(ch);
int i = Math.min(fromIndex, value.length - 2);
for (; i >= 0; i--) {
if (value[i] == hi && value[i + 1] == lo) {
return i;
}
}
}
return -1;
}
(2)
public int lastIndexOf(String str) {
return lastIndexOf(str, value.length);
}
public int lastIndexOf(String str, int fromIndex) {
return lastIndexOf(value, 0, value.length,
str.value, 0, str.value.length, fromIndex);
}
static int lastIndexOf(char[] source, int sourceOffset, int sourceCount,
char[] target, int targetOffset, int targetCount,
int fromIndex) {
/*
* Check arguments; return immediately where possible. For
* consistency, don't check for null str.
*/
int rightIndex = sourceCount - targetCount;
if (fromIndex < 0) {
return -1;
}
if (fromIndex > rightIndex) {
fromIndex = rightIndex;
}
/* Empty string always matches. */
if (targetCount == 0) {
return fromIndex;
}
int strLastIndex = targetOffset + targetCount - 1;
char strLastChar = target[strLastIndex];
int min = sourceOffset + targetCount - 1;
int i = min + fromIndex;
startSearchForLastChar:
while (true) {
while (i >= min && source[i] != strLastChar) {
i--;
}
if (i < min) {
return -1;
}
int j = i - 1;
int start = j - (targetCount - 1);
int k = strLastIndex - 1;
while (j > start) {
if (source[j--] != target[k--]) {
i--;
continue startSearchForLastChar;
}
}
return start - sourceOffset + 1;
}
}