replace 方法主要用于替换字符串中指定的字符或子字符串,Java 主要在 String 类和 StringBuilder/StringBuffer 类中提供了相关的 replace 方法,但它们的用法和效果有显著区别。

String.replace() 方法
这是最常用、最安全的 replace 方法,它属于 不可变 的 String 类,因此所有替换操作都会返回一个 新的字符串,而原始字符串保持不变。
String 类提供了两个重载的 replace 方法:
a) String.replace(char oldChar, char newChar)
- 功能: 替换字符串中所有出现的 单个字符
oldChar为newChar。 - 参数:
oldChar: 需要被替换的旧字符。newChar: 用于替换的新字符。
- 返回值: 一个新的
String对象,其中所有oldChar都被替换为newChar。 - 特点: 区分大小写。
示例代码:
public class StringReplaceExample {
public static void main(String[] args) {
String str = "hello world, hello java";
// 将所有 'l' 替换为 'p'
String newStr = str.replace('l', 'p');
System.out.println("原始字符串: " + str); // 输出: hello world, hello java
System.out.println("替换后字符串: " + newStr); // 输出: hepwo worpd, hep java
// 替换不存在的字符
String newStr2 = str.replace('z', 'x');
System.out.println("替换不存在的字符: " + newStr2); // 输出: hello world, hello java (原样返回)
}
}
b) String.replace(CharSequence target, CharSequence replacement)
- 功能: 替换字符串中所有出现的 子字符串
target为replacement。 - 参数:
target: 需要被替换的子字符串(CharSequence接口,可以是String)。replacement: 用于替换的新子字符串(CharSequence接口,可以是String)。
- 返回值: 一个新的
String对象,其中所有target子串都被替换为replacement子串。 - 特点: 区分大小写,这是 最常用 的
replace方法。
示例代码:

public class StringReplaceSequenceExample {
public static void main(String[] args) {
String str = "I like Java, Java is powerful.";
// 将所有 "Java" 替换为 "Python"
String newStr = str.replace("Java", "Python");
System.out.println("原始字符串: " + str); // 输出: I like Java, Java is powerful.
System.out.println("替换后字符串: " + newStr); // 输出: I like Python, Python is powerful.
// 替换一个不存在的子串
String newStr2 = str.replace("C++", "Go");
System.out.println("替换不存在的子串: " + newStr2); // 输出: I like Java, Java is powerful. (原样返回)
// 注意:区分大小写
String newStr3 = str.replace("java", "Kotlin");
System.out.println("区分大小写: " + newStr3); // 输出: I like Java, Java is powerful. (没有替换)
}
}
StringBuilder.replace() / StringBuffer.replace() 方法
与 String 不同,StringBuilder 和 StringBuffer 是 可变 的,它们的 replace 方法会 直接修改当前对象,而不是返回一个新的对象。
- 功能: 替换字符串中从指定
start到end索引范围内的内容。 - 参数:
start: 开始替换的索引(包含)。end: 结束替换的索引(不包含)。str: 用于替换的新字符串。
- 返回值: 返回
StringBuilder或StringBuffer对象本身,以便支持链式调用。 - 特点: 直接修改原对象,效率高(对于大量字符串操作),但线程不安全(
StringBuilder)或线程安全但性能稍差(StringBuffer)。
示例代码:
public class StringBuilderReplaceExample {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder("Hello World");
// 将索引 6 到 11 (即 "World") 替换为 "Java"
// 注意:replace的end索引是 exclusive (不包含) 的
StringBuilder result = sb.replace(6, 11, "Java");
System.out.println("原始 StringBuilder 对象: " + sb.toString()); // 输出: Hello Java
System.out.println("replace方法的返回值: " + result.toString()); // 输出: Hello Java
// 可以看到,原始对象 sb 和返回值 result 是同一个对象,并且内容已经被修改
// 链式调用示例
sb.append(" is great!")
.replace(6, 10, "Python"); // 将 "Java" 替换为 "Python"
System.out.println("链式调用后: " + sb.toString()); // 输出: Hello Python is great!
}
}
replaceAll() 和 replaceFirst() (正则表达式替换)
当你需要基于 模式(正则表达式)进行替换时,应该使用这两个方法。
a) String.replaceAll(String regex, String replacement)
- 功能: 使用给定的正则表达式
regex匹配字符串中的所有子串,并将其替换为replacement。 - 参数:
regex: 正则表达式。replacement: 替换字符串。
- 返回值: 一个新的
String对象。 - 注意:
replacement中包含特殊字符(如 ),它们会被视为反向引用。
示例代码:

public class ReplaceAllExample {
public static void main(String[] args) {
String str = "Order 123 is complete, Order 456 is pending.";
// 将所有 "Order" 后跟一个空格和数字的模式替换为 "Ticket"
String newStr = str.replaceAll("Order \\d+", "Ticket");
System.out.println("replaceAll 结果: " + newStr); // 输出: Ticket is complete, Ticket is pending.
// 反向引用示例:将 "apple, orange, banana" 替换为 "orange, apple, banana"
String fruits = "apple, orange, banana";
String swapped = fruits.replaceAll("(\\w+), (\\w+)", "$2, $1");
System.out.println("反向引用结果: " + swapped); // 输出: orange, apple, banana
// 解释: $1 对应第一个捕获组 (\\w+) -> "apple"
// $2 对应第二个捕获组 (\\w+) -> "orange"
}
}
b) String.replaceFirst(String regex, String replacement)
- 功能: 与
replaceAll类似,但它 只替换第一个匹配 的子串。 - 参数: 与
replaceAll相同。 - 返回值: 一个新的
String对象。
示例代码:
public class ReplaceFirstExample {
public static void main(String[] args) {
String str = "Order 123 is complete, Order 456 is pending.";
// 只替换第一个匹配的 "Order 数字"
String newStr = str.replaceFirst("Order \\d+", "Ticket");
System.out.println("replaceFirst 结果: " + newStr); // 输出: Ticket is complete, Order 456 is pending.
}
}
总结与对比
| 方法 | 所属类 | 功能 | 是否修改原对象 | 是否支持正则表达式 | 主要用途 |
|---|---|---|---|---|---|
replace(char, char) |
String |
替换所有单个字符 | 否 | 否 | 简单的字符替换 |
replace(CharSequence, CharSequence) |
String |
替换所有子字符串 | 否 | 否 | 最常用,精确的子串替换 |
replace(int, int, String) |
StringBuilder |
替换指定索引范围的内容 | 是 | 否 | 高效地、可变地修改字符串的一部分 |
replaceAll(String, String) |
String |
替换所有匹配正则表达式的子串 | 否 | 是 | 基于复杂模式(如数字、空格)的替换 |
replaceFirst(String, String) |
String |
替换第一个匹配正则表达式的子串 | 否 | 是 | 只替换第一个匹配项 |
如何选择?
-
简单替换一个或多个字符/固定子串?
- 使用
String.replace(CharSequence target, CharSequence replacement),这是最安全、最通用的选择。
- 使用
-
需要基于模式(如“所有数字”、“所有空格”)进行替换?
- 使用
String.replaceAll(String regex, String replacement),如果只想替换第一个匹配项,用replaceFirst。
- 使用
-
在一个循环中需要进行大量的字符串拼接和修改,追求高性能?
- 使用
StringBuilder或StringBuffer,并调用它们的replace(int, int, String)方法,这样可以避免创建大量中间字符串对象,减少内存开销和垃圾回收的压力。
- 使用
String 的不可变性是 Java 设计中的一个核心原则,它在多线程环境下提供了天然的安全性,而 StringBuilder 则是为了解决 String 在频繁修改时性能问题而设计的。
