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;
}
}