indexOf和lastIndexOf是Java中查找子串位置最常用且高效的方法,平均时间复杂度O(n),支持字符/子串查找及起始/截止位置指定,区分大小写、完全匹配;实用技巧包括用indexOf判断存在性、循环获取所有位置、组合提取中间内容,且比正则和split更轻量。

Java 中 indexOf 和 lastIndexOf 是查找子串位置最常用、也最高效的方法——它们由 JVM 底层优化,时间复杂度平均为 O(n),无需手动遍历,也不依赖正则引擎。
indexOf:从左往右找第一次出现的位置
它从字符串开头(索引 0)开始向右扫描,返回子串首次匹配的起始索引;没找到则返回 -1。
- 支持多种重载:查字符(
char)、查子串(String),还可指定起始搜索位置(如indexOf(String str, int fromIndex)) - 区分大小写,且匹配是**完全一致**的,不支持通配或模糊匹配
- 示例:
"hello world".indexOf("o")→ 返回 4(第一个 'o' 在索引 4);"abab".indexOf("ab", 1)→ 返回 2(从索引 1 开始找,第二个 "ab" 起始位置是 2)
lastIndexOf:从右往左找最后一次出现的位置
它从字符串末尾开始反向搜索,返回子串最后一次出现的起始索引;同样找不到时返回 -1。
- 也有对应重载:查
char、查String,以及指定搜索截止位置(如lastIndexOf(String str, int fromIndex),表示“只搜到索引 fromIndex 为止”,不是“从该位置开始”) - 注意:
lastIndexOf("a", 5)表示在 [0, 5] 范围内反向查找,不是从索引 5 往后找 - 示例:
"banana".lastIndexOf("na")→ 返回 4;"test".lastIndexOf("t", 2)→ 返回 0(因为只看前三个字符 "tes",最后一个 't' 在索引 0)
高效使用的实用技巧
这两个方法本身已足够快,但合理使用能避免常见坑:
立即学习“Java免费学习笔记(深入)”;
- 查是否存在子串?用
str.indexOf(sub) != -1,比str.contains(sub)更轻量(后者内部就是调用 indexOf) - 想获取所有匹配位置?不能只靠一次调用,需循环:每次从上一个结果 + 1 开始再查
indexOf - 提取中间内容?常组合使用:比如
str.substring(str.indexOf("(") + 1, str.lastIndexOf(")"))可取括号内文本(前提是确定存在) - 空字符串参数要小心:
"abc".indexOf("")永远返回 0(因空串在任意位置都“匹配”)
和正则、split 等方式对比
如果只是定位位置,indexOf/lastIndexOf 远快于 Pattern 或 split:
- 正则需编译、匹配、建 Matcher 对象,开销大;适合复杂模式,非简单子串查找
-
split会实际切分字符串、生成数组,内存和时间成本更高,仅当需要分割结果时才用 - 若需多次查找同一子串,且字符串很大,可考虑预处理(如构建 KMP 辅助数组),但日常开发中极少需要——JDK 的 indexOf 已针对常见场景做了充分优化


















