Java字符串四大類之String、StringBuffer、StringBuilder、StringJoiner詳解
前言
在 Java 開發(fā)中,字符串操作是高頻場景,而 String、StringBuffer、StringBuilder、StringJoiner 這四個類是處理字符串的核心工具。很多開發(fā)者在日常使用中容易混淆它們的特性和適用場景,本文將從「核心區(qū)別」「構(gòu)造方法」「常用方法」「實戰(zhàn)示例」四個維度全面拆解,幫助大家系統(tǒng)掌握,方便后續(xù)復(fù)習(xí)查閱。
一、核心區(qū)別總覽(復(fù)習(xí)核心)
這四個類的核心差異集中在「可變性」「線程安全」和「性能」上,是選擇使用場景的關(guān)鍵依據(jù)。用表格直觀呈現(xiàn):
| 類名 | 可變性 | 線程安全 | 性能 | 底層實現(xiàn) | 核心適用場景 |
|---|---|---|---|---|---|
| String | 不可變(final 修飾) | 安全(無修改操作,天然線程安全) | 最低(頻繁拼接產(chǎn)生大量臨時對象) | JDK8 及之前:char[];JDK9+:byte[](節(jié)省內(nèi)存) | 字符串常量、少量不修改的字符串(如配置項、固定文本) |
| StringBuilder | 可變 | 不安全(無同步鎖) | 最高(無鎖 overhead) | 可變 char[] 數(shù)組 | 單線程環(huán)境下頻繁拼接/修改字符串(日常開發(fā)首選) |
| StringBuffer | 可變 | 安全(方法加 synchronized 鎖) | 中等(比 StringBuilder 低 10%-20%) | 可變 char[] 數(shù)組 | 多線程環(huán)境下頻繁拼接/修改字符串(如多線程日志生成) |
| StringJoiner | 可變(封裝 StringBuilder) | 不安全(依賴底層 StringBuilder) | 與 StringBuilder 一致 | 內(nèi)部持有 StringBuilder 對象 | 帶分隔符的字符串拼接(如 a,b,c、[x,y,z],無需手動處理分隔符) |
二、逐個拆解:構(gòu)造方法 + 常用方法
每個類的構(gòu)造方法和常用方法是實際開發(fā)的基礎(chǔ),下面逐個梳理
1. String(不可變字符串)
String 是 Java 最基礎(chǔ)的字符串類,一旦創(chuàng)建,內(nèi)容無法修改。所有“修改”操作(如 substring、replace)都會生成新的 String 對象。
(1)核心構(gòu)造方法
| 構(gòu)造方法 | 說明 | 示例 |
|---|---|---|
| String() | 創(chuàng)建空字符串對象 | String str = new String(); |
| String(String original) | 通過已有字符串創(chuàng)建(復(fù)用內(nèi)容) | String str = new String(“hello”); |
| String(char[] value) | 通過字符數(shù)組創(chuàng)建 | char[] arr = {‘a’,‘b’,‘c’}; String str = new String(arr); |
| String(byte[] bytes) | 通過字節(jié)數(shù)組創(chuàng)建(使用默認(rèn)編碼) | byte[] bytes = “abc”.getBytes(); String str = new String(bytes); |
| String(byte[] bytes, String charsetName) | 通過字節(jié)數(shù)組+指定編碼創(chuàng)建 | String str = new String(bytes, “UTF-8”); |
(2)常用方法(必須掌握)
| 方法名 | 說明 | 示例 | 返回結(jié)果 |
|---|---|---|---|
| int length() | 獲取字符串長度 | “abc”.length() | 3 |
| char charAt(int index) | 獲取指定索引的字符(索引從 0 開始) | “abc”.charAt(1) | ‘b’ |
| String substring(int start, int end) | 截取子串(左閉右開,end 不包含) | “abcde”.substring(1,3) | “bc” |
| boolean equals(Object obj) | 比較字符串內(nèi)容(區(qū)分大小寫) | “abc”.equals(“ABC”) | false |
| boolean equalsIgnoreCase(String str) | 比較字符串內(nèi)容(忽略大小寫) | “abc”.equalsIgnoreCase(“ABC”) | true |
| int indexOf(String str) | 查找子串首次出現(xiàn)的索引(無則返回 -1) | “abcabc”.indexOf(“bc”) | 1 |
| String replace(CharSequence old, CharSequence new) | 替換字符/字符串 | “abac”.replace(“a”, “x”) | “xbxc” |
| String[] split(String regex) | 按分隔符拆分字符串(regex 支持正則) | “a,b,c”.split(“,”) | [“a”,“b”,“c”] |
| boolean isEmpty() | 判斷字符串是否為空(長度為 0) | “”.isEmpty() | true |
2. StringBuilder(可變、單線程首選)
專為單線程場景設(shè)計,可變字符序列,所有操作都在同一個對象上完成,無額外內(nèi)存開銷,是日常字符串拼接的最優(yōu)選擇。
(1)核心構(gòu)造方法
| 構(gòu)造方法 | 說明 | 示例 |
|---|---|---|
| StringBuilder() | 創(chuàng)建空對象,初始容量 16 | StringBuilder sb = new StringBuilder(); |
| StringBuilder(int capacity) | 指定初始容量(減少擴(kuò)容開銷,推薦) | StringBuilder sb = new StringBuilder(32); |
| StringBuilder(CharSequence seq) | 通過字符串/字符序列初始化 | StringBuilder sb = new StringBuilder(“hello”); |
(2)常用方法(必須掌握)
注:方法均返回自身對象,支持鏈?zhǔn)秸{(diào)用。
| 方法名 | 說明 | 示例(基于 sb = new StringBuilder(“abc”)) | 操作后 sb 內(nèi)容 |
|---|---|---|---|
| StringBuilder append(任意類型) | 拼接內(nèi)容(支持字符串、數(shù)字、對象等) | sb.append(123).append(“def”) | “abc123def” |
| String toString() | 轉(zhuǎn)換為最終的 String 對象(必調(diào)方法) | sb.toString() | “abc123def” |
| StringBuilder delete(int start, int end) | 刪除指定區(qū)間字符(左閉右開) | sb.delete(1,3) | “a123def” |
| StringBuilder insert(int offset, 任意類型) | 在指定位置插入內(nèi)容 | sb.insert(3, “xyz”) | “abcxyz123def” |
| StringBuilder reverse() | 反轉(zhuǎn)字符串 | sb.reverse() | “fed321cba” |
| int capacity() | 獲取當(dāng)前容量(底層數(shù)組長度) | sb.capacity() | 初始 16,擴(kuò)容后按 2*capacity+2 增長 |
| void setLength(int newLength) | 設(shè)置字符串長度(短則截斷,長則補(bǔ) ‘\0’) | sb.setLength(5) | “abc12” |
3. StringBuffer(可變、多線程安全)
與 StringBuilder 功能完全一致,唯一區(qū)別是所有方法都加了 synchronized 關(guān)鍵字,保證多線程安全,但性能略低。
(1)核心構(gòu)造方法
與 StringBuilder 完全相同:
// 1. 空構(gòu)造,初始容量 16
StringBuffer sb = new StringBuffer();
// 2. 指定初始容量
StringBuffer sb = new StringBuffer(64);
// 3. 用字符串初始化
StringBuffer sb = new StringBuffer("hello");
(2)常用方法
與 StringBuilder 完全相同,僅多了線程安全特性。示例(多線程拼接):
StringBuffer sb = new StringBuffer();
// 多線程拼接不會出現(xiàn)數(shù)據(jù)錯亂
new Thread(() -> sb.append("a")).start();
new Thread(() -> sb.append("b")).start();
// 最終 sb 內(nèi)容為 "ab" 或 "ba",但長度一定是 2(線程安全)
4. StringJoiner(JDK8+,分隔符拼接專用)
JDK8 引入的工具類,本質(zhì)是對 StringBuilder 的封裝,專為「帶分隔符的字符串拼接」設(shè)計,無需手動處理“最后多一個分隔符”的問題,語法更簡潔。
(1)核心構(gòu)造方法
| 構(gòu)造方法 | 說明 | 示例 |
|---|---|---|
| StringJoiner(CharSequence delimiter) | 僅指定分隔符 | StringJoiner joiner = new StringJoiner(“,”); |
| StringJoiner(CharSequence delimiter, CharSequence prefix, CharSequence suffix) | 指定分隔符 + 前綴 + 后綴(常用) | StringJoiner joiner = new StringJoiner(“,”, “[”, “]”); |
(2)常用方法
注:方法返回自身,支持鏈?zhǔn)秸{(diào)用。
| 方法名 | 說明 | 示例(基于 joiner = new StringJoiner(“,”, “[”, “]”)) | 操作后結(jié)果 |
|---|---|---|---|
| StringJoiner add(CharSequence newElement) | 添加拼接元素 | joiner.add(“Java”).add(“Python”).add(“Go”) | “[Java,Python,Go]” |
| String toString() | 轉(zhuǎn)換為最終 String 對象 | joiner.toString() | “[Java,Python,Go]” |
| StringJoiner merge(StringJoiner other) | 合并另一個 StringJoiner(復(fù)用分隔符/前綴/后綴) | joiner.merge(new StringJoiner(“,”).add(“C++”)) | “[Java,Python,Go,C++]” |
| StringJoiner setEmptyValue(CharSequence emptyValue) | 設(shè)置空值時的默認(rèn)輸出(無元素時生效) | new StringJoiner(“,”).setEmptyValue(“空”).toString() | “空” |
三、實戰(zhàn)示例對比(直觀理解差異)
用四個類分別實現(xiàn)「拼接 1-10 的數(shù)字為 “1,2,3,…,10”」,對比實現(xiàn)復(fù)雜度和性能:
import java.util.StringJoiner;
public class StringCompareDemo {
public static void main(String[] args) {
// 1. String(性能差,不推薦頻繁拼接)
String str = "";
for (int i = 1; i <= 10; i++) {
str += i + (i == 10 ? "" : ","); // 手動處理分隔符,頻繁生成臨時對象
}
System.out.println("String: " + str); // 輸出:1,2,3,4,5,6,7,8,9,10
// 2. StringBuilder(單線程推薦,高性能)
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= 10; i++) {
sb.append(i);
if (i != 10) sb.append(","); // 手動處理分隔符
}
System.out.println("StringBuilder: " + sb); // 輸出:1,2,3,4,5,6,7,8,9,10
// 3. StringBuffer(多線程用,單線程沒必要)
StringBuffer sbf = new StringBuffer();
for (int i = 1; i <= 10; i++) {
sbf.append(i).append(i == 10 ? "" : ",");
}
System.out.println("StringBuffer: " + sbf); // 輸出:1,2,3,4,5,6,7,8,9,10
// 4. StringJoiner(分隔符拼接最優(yōu),無需手動處理分隔符)
StringJoiner joiner = new StringJoiner(",");
for (int i = 1; i <= 10; i++) {
joiner.add(String.valueOf(i)); // 直接添加,自動處理分隔符
}
System.out.println("StringJoiner: " + joiner); // 輸出:1,2,3,4,5,6,7,8,9,10
}
}
四、總結(jié)(復(fù)習(xí)核心原則)
如果字符串無需修改(如常量、配置):用 String;
如果單線程環(huán)境下需要頻繁拼接/修改:用 StringBuilder(首選);
如果多線程環(huán)境下需要頻繁拼接/修改:用 StringBuffer;
如果需要拼接帶分隔符的字符串(如列表、數(shù)組轉(zhuǎn)字符串):用 StringJoiner(JDK8+)
到此這篇關(guān)于Java字符串四大類之String、StringBuffer、StringBuilder、StringJoiner的文章就介紹到這了,更多相關(guān)Java字符串String、StringBuffer、StringBuilder、StringJoiner內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java爬蟲實現(xiàn)Jsoup利用dom方法遍歷Document對象
本文主要介紹了Java爬蟲實現(xiàn)Jsoup利用dom方法遍歷Document對象,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05
在Java中動態(tài)執(zhí)行字符串代碼的方法小結(jié)
在Java編程中,靜態(tài)編譯的特性通常不允許我們直接執(zhí)行運行時生成的代碼,然而,有時我們需要動態(tài)地生成并執(zhí)行代碼片段,本文將詳細(xì)介紹如何在Java中運行一段字符串代碼,并提供詳細(xì)的代碼案例和運行結(jié)果,需要的朋友可以參考下2024-08-08

