一、方法定义

public synchronized StringBuffer replace(int start, int end, String str)

参数说明:

  • start:起始索引(包含),从0开始。
  • end:结束索引(不包含),即替换范围为 [start, end)
  • str:用于替换的字符串。

返回值:

  • 返回当前 StringBuffer 对象的引用(支持链式调用)。

异常:

  • StringIndexOutOfBoundsException:如果 start < 0end > 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"


六、注意事项

  1. 索引范围是左闭右开[start, end),即包含 start,不包含 end
  2. 允许 end == start:此时为插入操作,不删除任何字符。
  3. str 可为 null:会插入 "null" 字符串,而非空字符串。
  4. 线程安全:多线程共享时无需额外同步。
  5. ⚠️ 性能影响:替换后若长度变化大,可能触发内部数组扩容或数据迁移。

七、最佳实践

✅ 实践 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();

八、性能优化建议

  1. 批量操作优于多次小操作

    • 合并多个 replace() 为一次大范围替换。
    • 使用 StringBuilder 预处理内容,再一次性替换。
  2. 合理设置初始容量

    StringBuffer sb = new StringBuffer(expectedMaxLength);
    
  3. 避免在循环中频繁调用 replace()

    • 考虑先收集所有修改,再统一处理。
  4. 高并发场景权衡

    • StringBuffer 的同步开销可能成为瓶颈。
    • 可考虑 ThreadLocal<StringBuilder> + 最终合并策略。

总结

项目 说明
核心功能 安全替换指定范围的字符为新字符串
关键特性 线程安全、原地修改、支持链式调用
常用场景 动态文本修改、格式化、内容替换
使用技巧 可实现删除、插入、批量替换
性能提示 预设容量、减少频繁小替换、避免索引错误
替代方案 单线程可用 StringBuilder.replace() 提升性能

💡 一句话总结StringBuffer.replace(start, end, str) 是一个线程安全的文本替换方法,适用于多线程环境下的动态字符串修改。掌握其索引规则、异常边界和性能特性,能有效提升代码健壮性与效率。单线程场景建议使用 StringBuilder 以获得更高性能。