StringBuilder
上一節,我們學習了 Java 的 String
類,并介紹了其常用方法。本小節我們來介紹字符串的另外一個類:StringBuilder
,我們將會了解到 StringBuilder
與 String
的差異,StringBuilder
的使用場景,也會介紹與 StringBuilder
類對應的 StringBuffer
類,StringBuilder
的使用方法以及其常用方法是本小節的重點學習內容。
1. StringBuilder 概述
1.1 什么是 StringBuilder
與 String
相似,StringBuilder
也是一個與字符串相關的類,Java 官方文檔給 StringBuilder
的定義是:可變的字符序列。
1.2 為什么需要 StringBuilder
在 Java 字符串的學習中,我們知道了字符串具有不可變性,當頻繁操作字符串時候,會在常量池中產生很多無用的數據(回憶圖示)。
而 StringBuilder
與 String
不同,它具有可變性。相較 String
類不會產生大量無用數據,性能上會大大提高。
因此對于需要頻繁操作字符串的場景,建議使用 Stringbuilder
類來代替 String
類。
2. StringBuffer 概述
2.1 定義
了解了 StringBuilder
類 ,StringBuffer
也是不得不提的一個類,Java 官方文檔給出的定義是:線程安全的可變字符序列。
2.2 與前者的區別
StringBuffer
是 StringBuilder
的前身,在早期的 Java
版本中應用非常廣泛,它是 StringBuilder
的線程安全版本(線程我們將在后面的小節中介紹),但實現線程安全的代價是執行效率的下降。
你可以對比 StringBuilder
和 StringBuffer
的接口文檔,它們的接口基本上完全一致。為了提升我們代碼的執行效率,在如今的實際開發中 StringBuffer
并不常用。因此本小節的重點在 StringBuilder
的學習。
3. StringBuilder 的常用方法
3.1 構造方法
StringBuilder
類提供了如下 4 個構造方法:
StringBuilder()
構造一個空字符串生成器,初始容量為 16 個字符;StringBuilder(int catpacity)
構造一個空字符串生成器,初始容量由參數capacity
指定;StringBuilder(CharSequence seq)
構造一個字符串生成器,該生成器包含與指定的CharSequence
相同的字符。;StringBuilder(String str)
構造初始化為指定字符串內容的字符串生成器。
其中第 4 個構造方法最為常用,我們可以使用 StringBuilder
這樣初始化一個內容為 hello
的字符串:
StringBuilder str = new StringBuilder("Hello");
3.2 成員方法
StringBuilder
類下面也提供了很多與 String
類相似的成員方法,以方便我們對字符串進行操作。下面我們將舉例介紹一些常用的成員方法。
3.2.1 字符串連接
可以使用 StringBuilder
的 StringBuilder append(String str)
方法來實現字符串的連接操作。
我們知道,String
的連接操作是通過 +
操作符完成連接的:
String str1 = "Hello";
String str2 = "World";
String str3 = str1 + " " + str2;
如下是通過 StringBuilder
實現的字符串連接示例:
public class ConnectString1 {
public static void main(String[] args) {
// 初始化一個內容為 Hello 的字符串生成器
StringBuilder str = new StringBuilder("Hello");
// 調用append()方法進行字符串的連接
str.append(" ");
str.append("World");
System.out.println(str);
}
}
運行結果:
Hello World
由于 append()
方法返回的是一個 StringBuilder
類型,我們可以實現鏈式調用。例如,上述連續兩個 append()
方法的調用語句,可以簡化為一行語句:
str.append(" ").append("World");
如果你使用 IDE
編寫如上連接字符串的代碼,可能會有下面這樣的提示(IntelliJ idea 的代碼截圖):

提示內容說可以將 StringBuilder
類型可以替換為 String
類型,也就是說可以將上邊地代碼改為:
String str = "Hello" + " " + "World";
這樣寫并不會導致執行效率的下降,這是因為 Java 編譯器在編譯和運行期間會自動將字符串連接操作轉換為 StringBuilder
操作或者數組復制,間接地優化了由于 String
的不可變性引發的性能問題。
值得注意的是,append()
的重載方法有很多,可以實現各種類型的連接操作。例如我們可以連接 char
類型以及 float
類型,實例如下:
public class ConnectString2 {
public static void main(String[] args) {
StringBuilder str = new StringBuilder("小明的身高為");
str.append(':').append(172.5f);
System.out.println(str);
}
}
運行結果:
小明的身高為:172.5
上面代碼里連續的兩個 append()
方法分別調用的是重載方法 StringBuilder append(char c)
和 StringBuilder append(float f)
。
3.2.2 獲取容量
可以使用 int capacity()
方法來獲取當前容量,容量指定是可以存儲的字符數(包含已寫入字符),超過此數將進行自動分配。注意,容量與長度(length)不同,長度指的是已經寫入字符的長度。
例如,構造方法 StringBuilder()
構造一個空字符串生成器,初始容量為 16 個字符。我們可以獲取并打印它的容量,實例如下:
public class GetCapacity {
public static void main(String[] args) {
// 調用StringBuilder的無參構造方法,生成一個str對象
StringBuilder str = new StringBuilder();
System.out.println("str的初始容量為:" + str.capacity());
// 循環執行連接操作
for (int i = 0; i < 16; i ++) {
str.append(i);
}
System.out.println("連接操作后,str的容量為" + str.capacity());
}
}
運行結果:
str的初始容量為:16
連接操作后,str的容量為34
3.2.3 字符串替換
可以使用 StringBuilder replace(int start, int end, String str)
方法,來用指定字符串替換從索引位置 start
開始到 end
索引位置結束(不包含 end
)的子串。實例如下:
public class StringReplace {
public static void main(String[] args) {
// 初始化一個內容為 Hello 的字符串生成器
StringBuilder str = new StringBuilder("Hello World!");
// 調用字符串替換方法,將 World 替換為 Java
str.replace(6, 11, "Java");
// 打印替換后的字符串
System.out.println(str);
}
}
運行結果:
Hello Java!
也可使用 StringBuilder delete(int start, int end)
方法,先來刪除索引位置 start
開始到 end
索引位置(不包含 end
)的子串,再使用 StringBuilder insert(int offset, String str)
方法,將字符串插入到序列的 offset
索引位置。同樣可以實現字符串的替換,例如:
StringBuilder str = new StringBuilder("Hello World!");
str.delete(6, 11);
str.insert(6, "Java");
3.2.4 字符串截取
可以使用 StringBuilder substring(int start)
方法來進行字符串截取,例如,我們想截取字符串的后三個字符,實例如下:
public class StringSub {
public static void main(String[] args) {
StringBuilder str = new StringBuilder("你好,歡迎來到慕課網");
String substring = str.substring(7);
System.out.println("str截取后子串為:" + substring);
}
}
運行結果:
str截取后子串為:慕課網
如果我們想截取示例中的” 歡迎 “二字,可以使用重載方法 StringBuilder substring(int start, int end)
進行截?。?/p>
String substring = str.substring(3, 5);
3.2.5 字符串反轉
可以使用 StringBuildr reverse()
方法,對字符串進行反轉操作,例如:
public class StringReverse {
public static void main(String[] args) {
StringBuilder str = new StringBuilder("Hello Java");
System.out.println("str經過反轉操作后為:" + str.reverse());
}
}
運行結果:
str經過反轉操作后為:avaJ olleH
4. 小結
本小節我們介紹了 Java 的 StringBuilder
類,它具有可變性,對于頻繁操作字符串的場景,使用它來代替 String
類可以提高程序的執行效率;也知道了 StringBuffer
是 StringBuilder
的線程安全版本,官方更推薦使用 StringBuilder
;最后我們介紹了 StringBuilder
的常用構造方法和成員方法,如果你想了解更多關于 StringBuilder
的接口,可以翻閱官方文檔進行學習。