在大量字符串拼接操作時請使用StringBuffer解讀
StringBuffer的產(chǎn)生背景
StringBuffer是Java早期版本中引入的一個類,它的產(chǎn)生背景主要有以下幾個原因:
1. 解決String不可變性問題
- Java中的String對象是不可變的(immutable),每次修改String實際上都是創(chuàng)建新的String對象
- 頻繁修改字符串時會產(chǎn)生大量臨時對象,影響性能
- StringBuffer提供了可變的字符串緩沖區(qū),可以在原對象上修改而不創(chuàng)建新對象
2. 線程安全需求
- StringBuffer的方法都是同步的(synchronized),適合多線程環(huán)境下的字符串操作
- 早期Java版本中,多線程編程較為常見,需要線程安全的字符串操作類
3. 性能優(yōu)化
- 在大量字符串拼接操作時,使用StringBuffer比直接使用"+"操作符更高效
- StringBuffer內(nèi)部維護(hù)了一個可擴展的字符數(shù)組,減少了內(nèi)存分配和垃圾回收的開銷
4. 歷史原因
- StringBuffer在Java 1.0中就已經(jīng)存在
- 后來(Java 5)又引入了非線程安全的StringBuilder,作為單線程環(huán)境下的替代方案
StringBuffer的設(shè)計反映了早期Java對線程安全的重視,但隨著單線程應(yīng)用場景的增加,StringBuilder因其更高的性能而成為更常用的選擇。不過StringBuffer在多線程環(huán)境下仍然有其價值。
StringBuffer 詳解
1. StringBuffer 概述
StringBuffer 是 Java 中用于可變字符串操作的類,位于 java.lang 包中。
它提供了比 String 更高效的字符串修改方式,適用于頻繁修改字符串的場景,并且是線程安全的(方法使用 synchronized 修飾)。
主要特點:
- 可變性:可以直接修改字符串內(nèi)容,而不像
String每次修改都生成新對象。 - 線程安全:方法使用
synchronized修飾,適合多線程環(huán)境。 - 高效拼接:內(nèi)部維護(hù)一個動態(tài)擴容的字符數(shù)組,減少內(nèi)存分配和垃圾回收開銷。
2. StringBuffer 的構(gòu)造方法
| 構(gòu)造方法 | 說明 |
|---|---|
| StringBuffer() | 構(gòu)造一個初始容量為 16 的空緩沖區(qū) |
| StringBuffer(int capacity) | 構(gòu)造指定初始容量的空緩沖區(qū) |
| StringBuffer(String str) | 構(gòu)造一個初始內(nèi)容為 str 的緩沖區(qū),容量為 str.length() + 16 |
示例:
StringBuffer sb1 = new StringBuffer(); // 初始容量 16
StringBuffer sb2 = new StringBuffer(32); // 初始容量 32
StringBuffer sb3 = new StringBuffer("Hello"); // 初始內(nèi)容 "Hello",容量 21 (5 + 16)3. StringBuffer 的常用方法
(1) 增:append()和insert()
| 方法 | 說明 |
|---|---|
| append(xxx) | 在末尾追加數(shù)據(jù)(支持多種類型:int、char、String 等) |
| insert(int offset, xxx) | 在指定位置插入數(shù)據(jù) |
示例:
StringBuffer sb = new StringBuffer("Hello");
sb.append(" World"); // "Hello World"
sb.insert(5, ","); // "Hello, World"(2) 刪:delete()和deleteCharAt()
| 方法 | 說明 |
|---|---|
| delete(int start, int end) | 刪除 [start, end) 之間的字符 |
| deleteCharAt(int index) | 刪除指定位置的字符 |
示例:
StringBuffer sb = new StringBuffer("Hello, World");
sb.delete(5, 7); // "Hello World"(刪除 ", ")
sb.deleteCharAt(5); // "HelloWorld"(刪除空格)(3) 改:replace()和setCharAt()
| 方法 | 說明 |
|---|---|
| replace(int start, int end, String str) | 替換 [start, end) 之間的內(nèi)容為 str |
| setCharAt(int index, char ch) | 替換指定位置的字符 |
示例:
StringBuffer sb = new StringBuffer("Hello World");
sb.replace(6, 11, "Java"); // "Hello Java"
sb.setCharAt(0, 'h'); // "hello Java"(4) 查:charAt()、indexOf()、substring()
| 方法 | 說明 |
|---|---|
| charAt(int index) | 返回指定位置的字符 |
| indexOf(String str) | 返回 str 第一次出現(xiàn)的索引 |
| substring(int start, int end) | 返回 [start, end) 的子字符串 |
示例:
StringBuffer sb = new StringBuffer("Hello Java");
char ch = sb.charAt(6); // 'J'
int index = sb.indexOf("Java"); // 6
String sub = sb.substring(6, 10); // "Java"(5) 其他方法
| 方法 | 說明 |
|---|---|
| length() | 返回字符串長度 |
| capacity() | 返回當(dāng)前緩沖區(qū)容量 |
| reverse() | 反轉(zhuǎn)字符串 |
| toString() | 轉(zhuǎn)換為 String |
示例:
StringBuffer sb = new StringBuffer("Hello");
System.out.println(sb.length()); // 5
System.out.println(sb.capacity()); // 21 (5 + 16)
sb.reverse(); // "olleH"
String str = sb.toString(); // 轉(zhuǎn)換為 String4. StringBuffer 的擴容機制
默認(rèn)初始容量:16(如果未指定)。
擴容規(guī)則:
- 當(dāng)字符串長度超過當(dāng)前容量時,自動擴容。
- 新容量 = (舊容量 * 2) + 2。
- 如果仍然不夠,則直接擴容到所需的最小容量。
示例:
StringBuffer sb = new StringBuffer(); // 初始容量 16
sb.append("1234567890123456"); // 剛好 16 字符,不擴容
sb.append("X"); // 超過容量,擴容至 (16*2)+2 = 34
System.out.println(sb.capacity()); // 345. StringBuffer vs StringBuilder
| 對比項 | StringBuffer | StringBuilder |
|---|---|---|
| 線程安全 | ? 線程安全(synchronized) | ? 非線程安全 |
| 性能 | 稍慢(同步開銷) | 更快 |
| 適用場景 | 多線程環(huán)境 | 單線程環(huán)境 |
推薦使用:
- 單線程:優(yōu)先用
StringBuilder(更快)。 - 多線程:用
StringBuffer(線程安全)。
總結(jié)
StringBuffer 適用于頻繁修改字符串,比 String 更高效。
- 線程安全,但性能略低于
StringBuilder。 - 擴容機制:默認(rèn) 16,不夠時
(oldCapacity * 2) + 2。 - 主要方法:
append()、insert()、delete()、replace()、reverse()等。
適用場景:
- 多線程環(huán)境下的字符串拼接、修改。
- 需要頻繁修改字符串內(nèi)容時(如日志處理、動態(tài) SQL 拼接)。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java中使用Hutool的DsFactory操作多數(shù)據(jù)源的實現(xiàn)
在Java開發(fā)中,管理多個數(shù)據(jù)源是一項常見需求,Hutool作為一個全能的Java工具類庫,提供了DsFactory工具,幫助開發(fā)者便捷地操作多數(shù)據(jù)源,感興趣的可以了解一下2024-09-09
Java Apollo環(huán)境搭建以及集成SpringBoot案例詳解
這篇文章主要介紹了Java Apollo環(huán)境搭建以及集成SpringBoot案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08
一文講透為什么遍歷LinkedList要用增強型for循環(huán)
這篇文章主要為大家介紹了為什么遍歷LinkedList要用增強型for循環(huán)的透徹詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04
Mybatis實現(xiàn)ResultMap結(jié)果集
本文主要介紹了Mybatis實現(xiàn)ResultMap結(jié)果集,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04
Java rmi遠(yuǎn)程方法調(diào)用基本用法解析
這篇文章主要介紹了Java rmi遠(yuǎn)程方法調(diào)用基本用法解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-05-05

