一、方法定义
public synchronized StringBuffer replace(int start, int end, String str)
参数说明:
start
:起始索引(包含),从0开始。end
:结束索引(不包含),即替换范围为[start, end)
。str
:用于替换的字符串。
返回值:
- 返回当前
StringBuffer
对象的引用(支持链式调用)。
异常:
StringIndexOutOfBoundsException
:如果start < 0
、end > length()
或start > end
。
二、功能说明
replace()
方法用于将 StringBuffer
中指定范围 [start, end)
内的字符序列替换为给定的字符串 str
。该操作是原地修改(in-place),不会创建新的 StringBuffer
实例。
特点:
- 支持任意长度的替换:新字符串可以比原范围长或短。
- 线程安全:方法被
synchronized
修饰,可在多线程环境中安全调用。 - 支持链式调用:返回
this
,可连续调用其他方法。
三、示例代码
示例 1:基本替换
StringBuffer sb = new StringBuffer("Hello World");
sb.replace(6, 11, "Java"); // 将 "World" 替换为 "Java"
System.out.println(sb.toString()); // 输出:Hello Java
示例 2:替换为空字符串(删除效果)
StringBuffer sb = new StringBuffer("abcdef");
sb.replace(2, 4, ""); // 删除索引2到3的字符
System.out.println(sb.toString()); // 输出:abef
示例 3:插入式替换(长度扩展)
StringBuffer sb = new StringBuffer("abc");
sb.replace(3, 3, "def"); // 在末尾插入 "def"(end == start)
System.out.println(sb.toString()); // 输出:abcdef
示例 4:链式调用
StringBuffer sb = new StringBuffer("Hello Universe");
sb.replace(6, 14, "Beautiful ")
.insert(0, "Greetings: ")
.append("!");
System.out.println(sb.toString());
// 输出:Greetings: Hello Beautiful !
示例 5:异常处理
StringBuffer sb = new StringBuffer("test");
try {
sb.replace(1, 5, "xyz"); // end > length(),抛出异常
} catch (StringIndexOutOfBoundsException e) {
System.out.println("索引越界:" + e.getMessage());
}
四、使用技巧
技巧 1:实现“删除”功能
// 删除指定范围
sb.replace(start, end, "");
技巧 2:实现“插入”功能
// 在指定位置插入字符串
sb.replace(pos, pos, "newText");
技巧 3:替换所有匹配子串(配合 indexOf)
StringBuffer sb = new StringBuffer("a-b-c-d");
int index;
String target = "-";
String replacement = ",";
while ((index = sb.indexOf(target)) != -1) {
sb.replace(index, index + target.length(), replacement);
}
System.out.println(sb.toString()); // 输出:a,b,c,d
五、常见错误
❌ 错误 1:索引越界
StringBuffer sb = new StringBuffer("abc");
sb.replace(2, 5, "x"); // 抛出 StringIndexOutOfBoundsException
原因:
end=5
超出当前长度 3。
❌ 错误 2:start > end
sb.replace(3, 1, "xyz"); // 抛出异常
❌ 错误 3:null 字符串
sb.replace(0, 3, null); // 不会抛异常,但会插入字符串 "null"
注意:
str
可以为null
,此时会插入字符串"null"
。
六、注意事项
- ✅ 索引范围是左闭右开:
[start, end)
,即包含start
,不包含end
。 - ✅ 允许 end == start:此时为插入操作,不删除任何字符。
- ✅ str 可为 null:会插入
"null"
字符串,而非空字符串。 - ✅ 线程安全:多线程共享时无需额外同步。
- ⚠️ 性能影响:替换后若长度变化大,可能触发内部数组扩容或数据迁移。
七、最佳实践
✅ 实践 1:预估容量,减少扩容
// 若知道最终长度,预先设置容量
StringBuffer sb = new StringBuffer(1024);
sb.append("initial data");
sb.replace(0, 5, "replaced");
✅ 实践 2:避免频繁小范围替换
// ❌ 低效:多次小替换
for (int i = 0; i < 100; i++) {
sb.replace(i, i+1, String.valueOf(i));
}
// ✅ 更优:先构建新字符串再替换
StringBuilder temp = new StringBuilder();
for (int i = 0; i < 100; i++) {
temp.append(i);
}
sb.replace(0, 100, temp.toString());
✅ 实践 3:在多线程中安全使用
// 多个线程可安全调用 replace()
Thread t1 = () -> sb.replace(0, 3, "AAA");
Thread t2 = () -> sb.replace(3, 6, "BBB");
t1.start(); t2.start();
八、性能优化建议
批量操作优于多次小操作:
- 合并多个
replace()
为一次大范围替换。 - 使用
StringBuilder
预处理内容,再一次性替换。
- 合并多个
合理设置初始容量:
StringBuffer sb = new StringBuffer(expectedMaxLength);
避免在循环中频繁调用 replace():
- 考虑先收集所有修改,再统一处理。
高并发场景权衡:
StringBuffer
的同步开销可能成为瓶颈。- 可考虑
ThreadLocal<StringBuilder>
+ 最终合并策略。
总结
项目 | 说明 |
---|---|
核心功能 | 安全替换指定范围的字符为新字符串 |
关键特性 | 线程安全、原地修改、支持链式调用 |
常用场景 | 动态文本修改、格式化、内容替换 |
使用技巧 | 可实现删除、插入、批量替换 |
性能提示 | 预设容量、减少频繁小替换、避免索引错误 |
替代方案 | 单线程可用 StringBuilder.replace() 提升性能 |
💡 一句话总结:
StringBuffer.replace(start, end, str)
是一个线程安全的文本替换方法,适用于多线程环境下的动态字符串修改。掌握其索引规则、异常边界和性能特性,能有效提升代码健壮性与效率。单线程场景建议使用StringBuilder
以获得更高性能。