
本文详解如何正确实现字符串中英文句号(.)和感叹号(!)替换为"!!"的功能,指出原代码因边遍历边修改字符串导致逻辑错误,并提供基于stringbuilder的安全循环方案及正则替代方法。
在Java中,若需将用户输入文本中的所有英文句号(.)和感叹号(!)统一替换为双感叹号(!!),绝不可在for循环中直接修改正在遍历的字符串——因为String是不可变对象,每次text = front + "!!" + back都会创建新字符串,而循环索引i仍按原始长度递增,极易跳过字符、引发StringIndexOutOfBoundsException,甚至导致结果为空(如题中所述)。
✅ 正确做法是:分离“读取”与“构建”逻辑。使用charAt(i)高效获取单个字符(避免substring(i, i+1)的开销),并借助StringBuilder累积结果:
public static String replace(String text) {
StringBuilder sb = new StringBuilder(text.length()); // 预分配容量,提升性能
for (int i = 0; i < text.length(); i++) {
char c = text.charAt(i);
if (c == '.' || c == '!') {
sb.append("!!");
} else {
sb.append(c);
}
}
return sb.toString();
}该方案安全、高效、符合题目强制使用for循环的要求。StringBuilder的append()操作时间复杂度为O(1),整体算法为O(n),且避免了字符串拼接带来的内存浪费。
⚠️ 注意事项:
立即学习“Java免费学习笔记(深入)”;
- 不要使用text.substring(i, i+1).equals(".")——效率低且易出错(空字符串或越界时抛异常);
- StringBuilder比String +=快得多,尤其在频繁拼接场景;
- 若忽略“必须用for循环”的限制,一行正则即可解决:return text.replaceAll("[.!]", "!!");,但其内部不使用显式循环,仅作补充参考。
最终,当输入 "Hello. I am using Java!" 时,程序将准确输出:"Hello!! I am using Java!!" —— 每个目标标点均被无遗漏、无重复地替换为!!。










