StringBuilder.replace()StringBuilder 类中用于替换指定范围字符的重要方法。它允许你高效地修改字符串内容,而无需创建新的字符串对象。


一、方法定义

public StringBuilder replace(int start, int end, String str)

参数说明:

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

返回值:

  • 返回调用该方法的 StringBuilder 对象本身(支持链式调用)。

异常:

  • StringIndexOutOfBoundsException:如果 start < 0start > length()end < startend > length()

二、功能说明

  • 核心功能:将 StringBuilder 中从索引 startend-1 的字符子串,替换为指定的字符串 str
  • 原地修改:操作在原对象上进行,不创建新对象。
  • 长度可变:替换后的字符串长度可以与原范围不同(可变长替换)。
  • 支持 null:如果 strnull,则插入字符串 "null"

三、示例代码

示例 1:基本替换

StringBuilder sb = new StringBuilder("Hello World");
sb.replace(6, 11, "Java");
System.out.println(sb.toString()); // 输出:Hello Java
// 将 "World"(索引 6-10)替换为 "Java"

示例 2:替换为更短的字符串

StringBuilder sb = new StringBuilder("Hello World");
sb.replace(5, 11, "!");
System.out.println(sb.toString()); // 输出:Hello!
// 原 " World" 被 "!" 替代

示例 3:替换为更长的字符串

StringBuilder sb = new StringBuilder("Hello!");
sb.replace(5, 6, " Beautiful World");
System.out.println(sb.toString()); // 输出:Hello Beautiful World!
// 在索引 5(空格位置)插入长字符串

示例 4:插入功能(start == end)

StringBuilder sb = new StringBuilder("Hello");
sb.replace(5, 5, " World");
System.out.println(sb.toString()); // 输出:Hello World
// 在末尾插入 " World",相当于 insert(5, " World")

示例 5:删除功能(替换为空字符串)

StringBuilder sb = new StringBuilder("Hello World");
sb.replace(5, 6, ""); // 或 sb.replace(5, 6, null) → 插入 "null"
System.out.println(sb.toString()); // 输出:HelloWorld
// 删除索引 5 处的空格

示例 6:链式调用

StringBuilder sb = new StringBuilder("A-B-C-D");
sb.replace(0, 1, "X")
  .replace(2, 3, "Y")
  .replace(4, 5, "Z");
System.out.println(sb.toString()); // 输出:X-Y-Z-D

示例 7:处理 null

StringBuilder sb = new StringBuilder("Hello");
sb.replace(5, 5, null);
System.out.println(sb.toString()); // 输出:Hellonull
// 插入字符串 "null"

四、使用技巧

技巧 1:实现“插入”功能

start == end 时,replace() 等效于 insert()

sb.replace(pos, pos, "newStr"); // 在 pos 位置插入

技巧 2:实现“删除”功能

用空字符串替换目标范围:

sb.replace(start, end, ""); // 删除 [start, end) 范围

技巧 3:批量替换(结合循环)

StringBuilder sb = new StringBuilder("Error: ERROR_CODE_1, error: ERROR_CODE_2");
// 统一替换所有 "error" 相关词为大写
int index = 0;
while ((index = sb.indexOf("error", index)) != -1) {
    sb.replace(index, index + 5, "ERROR");
    index += 5; // 跳过已替换部分
}

技巧 4:与 indexOf() 配合定位

StringBuilder sb = new StringBuilder("User: alice, Status: active");
int start = sb.indexOf("Status: ");
if (start != -1) {
    int end = start + 8 + 6; // "Status: ".length() + "active".length()
    sb.replace(start, end, "Status: inactive");
}

五、常见错误

错误 1:索引越界

StringBuilder sb = new StringBuilder("Hi");
sb.replace(5, 6, "Hello"); 
// 抛出 StringIndexOutOfBoundsException
// 原因:start=5 > length()=2

错误 2:end < start

sb.replace(3, 1, "test"); 
// 抛出 StringIndexOutOfBoundsException

错误 3:混淆“包含”与“不包含”

StringBuilder sb = new StringBuilder("Hello");
// 想替换 "llo"(索引 2,3,4),错误写法:
sb.replace(2, 4, "XX"); // 只替换索引 2,3 → "HeXXo"
// 正确写法:
sb.replace(2, 5, "XX"); // 替换索引 2,3,4 → "HeXX"

六、注意事项

  1. 左闭右开区间end 索引不包含在替换范围内,即 [start, end)
  2. 自动扩容:如果替换后的总长度超过当前容量,会自动扩容。
  3. null 处理:传入 null 会被当作字符串 "null" 插入。
  4. 原地修改:方法修改原对象,不影响之前通过 toString() 生成的 String
  5. 性能影响:若替换范围较小但新字符串很长,可能触发数组复制。

七、最佳实践与性能优化

1. 预判索引有效性

int len = sb.length();
if (start >= 0 && start <= len && end >= start && end <= len) {
    sb.replace(start, end, str);
} else {
    // 处理异常情况
}

2. 避免频繁大范围替换

  • 频繁替换可能导致内部数组多次复制。
  • 若需大规模重构,考虑重新构建 StringBuilder

3. 结合 ensureCapacity() 预分配

// 预估替换后最大长度
sb.ensureCapacity(sb.length() + expectedGrowth);
sb.replace(start, end, longString);

4. 使用 setCharAt() 替代单字符替换

// 更高效(无需数组移动)
sb.setCharAt(0, 'h');
// 而不是
// sb.replace(0, 1, "h");

5. 性能对比:replace vs delete + append

  • replace(start, end, str) 内部等价于 delete(start, end).insert(start, str)
  • 直接使用 replace() 更简洁,性能相同。

八、总结

要点 说明
核心作用 高效替换指定范围的字符子串
关键参数 start(包含)、end(不包含)、str(新字符串)
返回值 自身,支持链式调用
异常 StringIndexOutOfBoundsException(索引无效)
常用技巧 实现插入(start==end)、删除(str=""
常见错误 索引越界、混淆区间包含性
最佳实践 验证索引、预分配容量、避免滥用
性能提示 单字符替换用 setCharAt,大范围修改评估成本

最终建议

StringBuilder.replace() 是一个强大且高效的字符串修改工具。掌握其“左闭右开”的索引规则是避免错误的关键。在实际开发中,优先用于中等范围的文本替换、插入和删除操作。结合 indexOf() 定位目标位置,能实现灵活的文本处理逻辑。记住:正确使用索引,预判边界,即可安全高效地驾驭此方法