用string.indexof配合循环统计子串出现次数的核心是动态更新搜索起始位置:每次从上一次匹配位置加子串长度处继续查找,直到indexof返回-1;需显式处理空子串、null等边界情况。

用 String.indexOf 配合循环统计子串出现次数,核心思路是:每次从上一次找到位置的**后一位**开始继续搜索,直到返回 -1。
关键点:起始搜索位置要动态更新
不能每次都从 0 开始查,否则会无限循环或重复计数。每次调用 indexOf(str, fromIndex) 时,fromIndex 应设为上一次匹配位置 + 子串长度。
- 初始
fromIndex = 0 - 找到一次后,更新为
index + str.length() - 当
indexOf返回 -1,说明没更多匹配,退出循环
基础实现(推荐)
这是最清晰、不易出错的方式:
public static int countSubstring(String text, String sub) {
if (text == null || sub == null || sub.length() == 0 || text.length() == 0) {
return 0;
}
int count = 0;
int index = 0;
while ((index = text.indexOf(sub, index)) != -1) {
count++;
index += sub.length(); // 移动到子串之后,避免重叠匹配
}
return count;
}
例如:countSubstring("abababa", "aba") 返回 2(位置 0 和 4,不重叠);若想支持重叠匹配(如位置 0、2、4),则把 index += 1 即可。
注意空字符串和边界情况
indexOf 对空字符串 "" 的行为特殊:只要原字符串非 null,"abc".indexOf("") 总是返回 0。所以必须显式判断 sub.length() == 0,否则会陷入死循环或返回错误结果。
- 空子串 → 直接返回 0(语义上无意义)或按需抛异常
- 原字符串为空或为 null → 返回 0
- 子串比原字符串长 → 循环不会执行,直接返回 0
替代方案:用正则(仅作对比,不推荐用于简单计数)
虽然 Pattern.compile("abc").matcher(str).results().count() 更函数式,但创建 Pattern 和 Matcher 开销大,且对简单子串查找属于过度设计。除非需要复杂匹配逻辑,否则坚持用 indexOf 循环更高效、直观。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











