String-重要方法的原始碼解析
1. String的底層實現
String 內部實際儲存結構為 char 陣列,原始碼如下:
public final class String
implements java.io.Serializable, Comparable\<String\>, CharSequence {
// 用於儲存字串的值
private final char value[];
// 快取字串的 hash code
private int hash; // Default to 0
// ......其他內容
}
String 原始碼中包含下面幾個重要的方法。
2. 多構造方法
String 字串有以下 4 個重要的構造方法:
// String 為引數的構造方法 public String(String original) { this.value = original.value; this.hash = original.hash; } // char[] 為引數構造方法 public String(char value[]) { this.value = Arrays.copyOf(value, value.length); } // StringBuffer 為引數的構造方法 public String(StringBuffer buffer) { synchronized(buffer) { this.value = Arrays.copyOf(buffer.getValue(), buffer.length()); } } // StringBuilder 為引數的構造方法 public String(StringBuilder builder) { this.value = Arrays.copyOf(builder.getValue(), builder.length()); }
其中,比較容易被我們忽略的是以 StringBuffer 和 StringBuilder
為引數的建構函式,因為這三種資料型別,我們通常都是單獨使用的,所以這個小細節我們需要特別留意一下。
3. equals() 比較兩個字串是否相等
原始碼如下:
public boolean equals(Object anObject) { // 物件引用相同直接返回 true if (this == anObject) { return true; } // 判斷需要對比的值是否為 String 型別,如果不是則直接返回 false if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { // 把兩個字串都轉換為 char 陣列對比 char v1[] = value; char v2[] = anotherString.value; int i = 0; // 迴圈比對兩個字串的每一個字元 while (n-- != 0) { // 如果其中有一個字元不相等就 true false,否則繼續對比 if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }
String 型別重寫了 Object 中的 equals() 方法,equals() 方法需要傳遞一個 Object 型別的引數值,在比較時會先通過
instanceof 判斷是否為 String 型別,如果不是則會直接返回 false,instanceof 的使用如下:
Object oString = "123";
Object oInt = 123;
System.out.println(oString instanceof String); // 返回 true
System.out.println(oInt instanceof String); // 返回 false
當判斷引數為
String 型別之後,會迴圈對比兩個字串中的每一個字元,當所有字元都相等時返回 true,否則則返回
false。
還有一個和 equals() 比較類似的方法
equalsIgnoreCase(),它是用於忽略字串的大小寫之後進行字串對比。
4. compareTo() 比較兩個字串
compareTo() 方法用於比較兩個字串,返回的結果為 int 型別的值,原始碼如下:
public int compareTo(String anotherString) {
int len1 = value.length;
int len2 = anotherString.value.length;
// 獲取到兩個字串長度最短的那個 int 值
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;
}
從原始碼中可以看出,compareTo() 方法會迴圈對比所有的字元,當兩個字串中有任意一個字元不相同時,則
return char1-char2。比如,兩個字串分別儲存的是 1 和 2,返回的值是
-1;如果儲存的是 1 和 1,則返回的值是 0 ,如果儲存的是 2 和 1,則返回的值是 1。
還有一個和 compareTo() 比較類似的方法
compareToIgnoreCase(),用於忽略大小寫後比較兩個字串。
可以看出 compareTo() 方法和 equals() 方法都是用於比較兩個字串的,但它們有兩點不同:
-
equals() 可以接收一個 Object 型別的引數,而
compareTo() 只能接收一個 String 型別的引數; -
equals() 返回值為 Boolean,而 compareTo() 的返回值則為 int。
它們都可以用於兩個字串的比較,當 equals() 方法返回 true 時,或者是 compareTo() 方法返回
0 時,則表示兩個字串完全相同。
5. 其他重要方法
方法名 | 作用 |
---|---|
indexOf() | 查詢字串首次出現的下標位置 |
lastIndexOf() | 查詢字串最後出現的下標位置 |
contains() | 查詢字串中是否包含另一個字串 |
toLowerCase() | 把字串全部轉換成小寫 |
toUpperCase() | 把字串全部轉換成大寫 |
length() | 查詢字串的長度 |
trim() | 去掉字串首尾空格 |
replace() | 替換字串中的某些字元 |
split() | 把字串分割並返回字串陣列 |
join() | 把字串陣列轉為字串 |