1. 程式人生 > 其它 >java string內容差異對比_Java 面試真題 String 的特點是什麼?它有哪些重要的方法?...

java string內容差異對比_Java 面試真題 String 的特點是什麼?它有哪些重要的方法?...

技術標籤:java string內容差異對比

作者簡介

王磊

前 360 技術專家,十多年 Java 老兵。

本文選自拉勾專欄:《Java面試真題及原始碼34講

你好,我是王磊,Java 面試真題及原始碼 34 講專欄作者。前 360 技術專家,10 多年Java老兵,5 年大廠面試官經驗。擁有 10 多年大型系統設計、開發和調優經驗。這篇內容來自我的「Java 面試真題及原始碼 34 講」的 01 講。

幾乎所有的 Java 面試都是以 String 開始,如果第一個問題沒有回答好,則會給面試官留下非常不好的第一印象,而糟糕的第一印象則會直接影響到自己的面試結果,心理學把這種現象叫做印刻效應。所以對於 String 的知識,我們必須深入的掌握才能為自己贏得更多的籌碼。

本次要討論的問題是:String 是如何實現的?它有哪些重要的方法?

典型回答

以主流的 JDK 版本 1.8 來說,String 內部實際儲存結構為 char 陣列,原始碼如下:

public final class String
implements java.io.Serializable, Comparable, CharSequence {
// 用於儲存字串的值
private final char value[];
// 快取字串的 hash code
private int hash; // Default to 0
// ......其他內容
}

String 原始碼中包含下面幾個重要的方法。

1. 多構造方法

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 為引數的建構函式,因為這三種資料型別,我們通常都是單獨使用的,所以這個小細節我們需要特別留意一下。

2. 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(),它是用於忽略字串的大小寫之後進行字串對比。

3. 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() 方法都是用於比較兩個字串的,但它們有兩點不同:

1.equals() 可以接收一個 Object 型別的引數,而 compareTo() 只能接收一個 String 型別的引數;

2.equals() 返回值為 Boolean,而 compareTo() 的返回值則為 int。

它們都可以用於兩個字串的比較,當 equals() 方法返回 true 時,或者是 compareTo() 方法返回 0 時,則表示兩個字串完全相同。

4. 其他重要方法

  • indexOf():查詢字串首次出現的下標位置

  • lastIndexOf():查詢字串最後出現的下標位置

  • contains():查詢字串中是否包含另一個字串

  • toLowerCase():把字串全部轉換成小寫

  • toUpperCase():把字串全部轉換成大寫

  • length():查詢字串的長度

  • trim():去掉字串首尾空格

  • replace():替換字串中的某些字元

  • split():把字串分割並返回字串陣列

  • join():把字串陣列轉為字串

be0411c4b807522a19da5bad3e2ffdc7.png小結 b2882f6068208ab38c59b03b26f18a6a.png

本課時從 String 的原始碼入手,重點講了 String 的構造方法、equals() 方法和 compareTo() 方法,其中 equals() 重寫了 Object 的 equals() 方法,把引用對比改成了字串值對比。

OK,本次分析就到這裡啦,下一次我將分享“HashMap 底層實現原理是什麼?JDK8 做了哪些優化?”你可以點選閱讀原文,提前檢視後面的內容哦~

版權宣告:本文版權歸屬拉勾教育及該專欄作者,任何媒體、網站或個人未經本網協議授權不得轉載、連結、轉貼或以其他方式複製釋出/發表,違者必究。

90e49a56c9ea73014444bd6d0876d608.gif