java中查找子串最常用indexof和contains:前者返回起始索引(未找到为-1),适合定位;后者返回布尔值,语义更清晰,适合存在性判断。

Java中查找子串最常用的是indexOf和contains,二者底层都基于字符遍历,但用途和返回值不同:前者返回位置索引,适合需要定位的场景;后者返回布尔值,适合单纯判断是否存在。
用indexOf精准定位子串起始位置
indexOf有多个重载版本,最常用的是String.indexOf(String str),从头开始搜索,找到第一个匹配就返回下标(从0开始);没找到返回-1。注意它区分大小写,且不支持正则。
- 查找首次出现位置:
"Hello World".indexOf("o")→ 返回4 - 从指定位置继续查找:
"banana".indexOf("na", 3)→ 从索引3开始找,返回4 - 判断是否存在时,别直接用
if (str.indexOf("abc")),因为返回0会被当成false;应写成if (str.indexOf("abc") != -1)
用contains快速判断子串存在性
contains是JDK 1.5引入的语法糖,内部其实就调用了indexOf >= 0,语义更清晰、代码更易读,适合“有/无”的二元判断。
OpenJDK 24 Windows x64 官方参考实现(24+36),适合 Windows 环境进行 Java 开发、编译、运行和版本兼容性验证。
- 推荐写法:
if (str.contains("error")) { ... },比indexOf != -1直观 - 不能获取位置信息,也不支持忽略大小写的内置选项,如需忽略大小写,可先转统一大小写:
str.toLowerCase().contains("test") - 传入
null会抛NullPointerException,使用前建议判空
常见误区与替代方案
这两个方法都只支持字面量匹配,无法处理模糊、通配或正则需求。遇到复杂匹配,需切换策略:
- 忽略大小写全匹配:用
equalsIgnoreCase或正则Pattern.compile("xxx", Pattern.CASE_INSENSITIVE) - 统计出现次数:不能单靠
indexOf,需循环调用并更新起始位置 - 查找所有匹配位置:用
while配合indexOf累加偏移,或改用正则Matcher.find() - 中文、emoji等Unicode字符要注意:Java中
char是UTF-16编码单位,某些字符占两个char(即一个代理对),indexOf按char索引,不是按“字符”计数,必要时用String.codePointAt()和Character.isSupplementaryCodePoint()辅助
性能与适用场景总结
两者时间复杂度都是O(n×m)(n为主串长,m为子串长),在大多数业务场景中性能差异可忽略。选择依据主要是语义需求:
- 要位置、要多次查找、要控制起始点 → 选
indexOf - 只关心“有没有”,强调可读性和简洁性 → 选
contains - 子串长度为0(空字符串)时,
indexOf("")恒返回0,contains("")恒返回true,这是符合规范的设计,不是bug
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










