目录
- StringBuffer的产生背景
- 1. 解决String不可变性问题
- 2. 线程安全需求
- 3. 性能优化
- 4. 历史原因
- StringBuffer 详解
- 1. StringBuffer 概述
- 2. StringBuffer 的构造方法
- 3. StringBuffer 的常用方法
- (1) 增:append()和insert()
- (2) 删:delete()和deleteCharAt()
- (3) 改:replacejs()和setCharAt()
- (4) 查:charAt()、indexOf()、substring()
- (5) 其他方法
- 4. StringBuffer 的扩容机制
- 5. StringBuffer vs StringBuilder
- 总结
StringBuffer的产生背景
StringBuffer是Java早期版本中引入的一个类,它的产生背景主要有以下几个原因:
1. 解决String不可变性问题
- Java中的String对象是不可变的(immutable),每次修改String实际上都是创建新的String对象
- 频繁修改字符串时会产生大量临时对象,影响性能
- StringBuffer提供了可变的字符串缓冲区,可以在原对象上修改而不创建新对象
2. 线程安全需求
- StringBuffer的方法都是同步的(synchronized),适合多线程环境下的字符串操作
- 早期Java版本中,多线程编程较为常见,需要线程安全的字符串操作类
3. 性能优化
- 在大量字符串拼接操作时,使用StringBuffer比直接使用"+"操作符更高效
- StringBuffer内部维护了一个可扩展的字符数组,减少了内存分配和垃圾回收的开销
4. 历史原因
- StringBuffer在Java 1.0中就已经存在
- 后来(Java 5)又引入了非线程安全的StringBuilder,作为单线程环境下的替代方案
StringBuffer的设计反映了早期Java对线程安全的重视,但随着单线程应用场景的增加,StringBuilder因其更高的性能而成为更常用的选择。不过StringBuffer在多线程环境下仍然有其价值。
StringBuffer 详解
1. StringBuffer 概述
StringBuffer
是 Java 中用于可变字符串操作的类,位于 java.lang
包中。
它提供了比 String
更高效的字符串修改方式,适用于频繁修改字符串的场景,并且是线程安全的(方法使用 synchronized
修饰)。
主要特点:
- 可变性:可以直接修改字符串内容,而不像
String
每次修改都生成新对象。 - 线程安全:方法使用
synchronized
修饰,适合多线程环境。 - 高效拼接:内部维护一个动态扩容的字符数组,减少内存分配和垃圾回收开销。
2. StringBuffer 的构造方法
构造方法 | 说明 |
---|---|
StringBuffer() | 构造一个初始容量为 16 的空缓冲区 |
StringBuffer(int capacity) | 构造指定初始容量的空缓冲区 |
StringBuffer(String str) | 构造一个初始内容为 str 的缓冲区,容量为 str.length() + 16 |
示例:
StringBuffer sb1 = new StringBuffer(); // 初始容量 16 StringBuffer sb2 = new StringBuffer(32); // 初始容量 32 StringBuffer sb3 = new StringBuffer("Hello"); // 初始内容 "Hello",容量 21 (5 + 16)
3. StringBuffer 的常用方法
(1) 增:append()和insert()
方法 | 说明 |
---|---|
aphttp://www.devze.compend(xxx) | 在末尾追加数据(支持多种类型:int、char、String 等) |
insert(int offset, xxx) | 在指定位置插入数据 |
示例:
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()
方法 | 说明 |
---|---|
repla编程客栈ce(int start, int end, String str) | 替换 [start, end) 之间的内容为 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 第一次出现的索引 |
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() | 返回当前缓冲区容量 |
reverse() | 反转字符串 |
toString() | 转换为 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(); // 转换为 String
4. StringBuffer 的扩容机制
默认初始容量:16(如果未指定)。
扩容规则:
- 当字符串长度超过当前容量时,自动扩容。
- 新容量 = (旧容量 * 2) + 2。
- 如果仍然不够,则直接扩容到所需的最小容量。
示例:
StringBuffer sb = new StringBuffer(); // 初始容量 16 sb.append("1234567890123456"); // 刚好 16 字符,不扩容 sb.append("X"); // 超过容量,扩容至 (16*2)+2 = 34 System.out.println(sb.capacity()); // 34
5. StringBuffer vs StringBuilder
对比项 | StringBuffer | StringBuilder |
---|---|---|
线程安全 | ✅ 线程安全(synchronized) | ❌ 非线程安全 |
性能 | 稍慢(同步开销) | 更快 |
适用场景 | 多线程环境 | 单线程环境 |
推荐使用:
- 单线程:优先用
StringBuilder
(更快)。 - 多线程:用
StringBuffer
(线程安全)。
总结
StringBuffer
适用于频繁修改字符串,比 String
更高效。
- 线程安全,但性能略低于
StringBuilder
。 - 扩容机制:默认 16,不够时
(oldCapacity * 2) + 2
。 - 主要方法:
apjavascriptpend()
、insert()
、delete()
、replace()
、reverse()
等。
适用场景:
- 多线程环境下的字符串拼接、修改。
- 需要频繁修改字符串内容时(如日志处理、动态 SQL 拼接)。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。
精彩评论