Java 查找字符串最后一次出现的位置
在 Java 开发中,查找字符串中字符或子串最后一次出现的位置是高频需求(如解析文件路径、提取后缀名、处理 URL 等场景)。核心依赖 一、核心方法:
场景 3:从指定位置向前查找(含
String 类的 lastIndexOf() 方法,该方法提供多种重载形式,适配不同查找场景。本文通过实例详解所有用法、返回规则及实际应用场景。
一、核心方法:lastIndexOf() 重载说明
String 类提供 4 个 lastIndexOf() 重载方法,均返回目标字符 / 子串在原字符串中最后一次出现的索引(索引从 0 开始);若未找到,返回 -1。| 方法签名 | 功能说明 |
|---|---|
int lastIndexOf(int ch) |
查找单个字符(ch 为字符的 Unicode 编码,可直接传字符或对应 int 值)最后一次出现的索引。 |
int lastIndexOf(int ch, int fromIndex) |
从指定索引 fromIndex 开始向前查找(包含 fromIndex),返回字符 ch 最后一次出现的索引。 |
int lastIndexOf(String str) |
查找子字符串 str 最后一次出现的索引(子串需完整匹配)。 |
int lastIndexOf(String str, int fromIndex) |
从指定索引 fromIndex 开始向前查找,返回子串 str 最后一次出现的索引。 |
关键规则:
- 索引从 0 开始(如 "abc" 中 'a' 索引为 0,'c' 为 2)。
fromIndex超出范围时:- 若
fromIndex >= 字符串长度:等效于从字符串末尾开始查找。 - 若
fromIndex < 0:等效于从索引 0 开始查找(即全串查找,但仍返回最后一次出现位置)。
- 若
- 查找空字符串
""时,返回字符串的长度(如 "test".lastIndexOf ("") → 4)。
二、实例场景详解(附完整代码)
场景 1:查找单个字符最后一次出现的位置
需求:
已知字符串
str = "Hello, Java! Java is easy.",查找字符 'a' 和 '!' 最后一次出现的位置。代码实现:
public class LastIndexOfDemo {
public static void main(String[] args) {
String str = "Hello, Java! Java is easy.";
// 1. 查找字符 'a' 最后一次出现的位置
int indexA = str.lastIndexOf('a');
System.out.println("字符 'a' 最后一次出现的索引:" + indexA); // 输出:18(对应第二个 Java 中的 'a')
// 2. 查找字符 '!' 最后一次出现的位置
int indexExclaim = str.lastIndexOf('!');
System.out.println("字符 '!' 最后一次出现的索引:" + indexExclaim); // 输出:9(仅出现一次)
// 3. 查找不存在的字符(返回 -1)
int indexZ = str.lastIndexOf('z');
System.out.println("字符 'z' 最后一次出现的索引:" + indexZ); // 输出:-1
}
}
场景 2:查找子字符串最后一次出现的位置
需求:
在上述字符串中,查找子串
"Java" 和 "is" 最后一次出现的位置。代码实现:
public class LastIndexOfSubstringDemo {
public static void main(String[] args) {
String str = "Hello, Java! Java is easy.";
// 1. 查找子串 "Java" 最后一次出现的位置(子串首字符索引)
int indexJava = str.lastIndexOf("Java");
System.out.println("子串 \"Java\" 最后一次出现的索引:" + indexJava); // 输出:12(第二个 Java 的 'J' 索引)
// 2. 查找子串 "is" 最后一次出现的位置
int indexIs = str.lastIndexOf("is");
System.out.println("子串 \"is\" 最后一次出现的索引:" + indexIs); // 输出:17
// 3. 查找不存在的子串(返回 -1)
int indexPython = str.lastIndexOf("Python");
System.out.println("子串 \"Python\" 最后一次出现的索引:" + indexPython); // 输出:-1
}
}
场景 3:从指定位置向前查找(含 fromIndex 参数)
需求:
在字符串
str = "abacadaeaf" 中,从索引 8 开始向前查找字符 'a',从索引 5 开始向前查找子串 "ada"。代码实现:
public class LastIndexOfFromIndexDemo {
public static void main(String[] args) {
String str = "abacadaeaf"; // 索引:0:a,1:b,2:a,3:c,4:a,5:d,6:a,7:e,8:a,9:f
// 1. 从索引 8 开始向前查找 'a'(包含索引8)
int indexA1 = str.lastIndexOf('a', 8);
System.out.println("从索引8向前查找 'a' 的位置:" + indexA1); // 输出:8(索引8本身是 'a')
// 2. 从索引 7 开始向前查找 'a'(不包含索引8)
int indexA2 = str.lastIndexOf('a', 7);
System.out.println("从索引7向前查找 'a' 的位置:" + indexA2); // 输出:6
// 3. 从索引 5 开始向前查找子串 "ada"(子串需完整匹配)
int indexAda = str.lastIndexOf("ada", 5);
System.out.println("从索引5向前查找 \"ada\" 的位置:" + indexAda); // 输出:4(子串 "ada" 对应索引4-6,但 fromIndex=5,仅匹配4-5?不,子串长度3,从5向前找,实际匹配索引4-6是否在范围,这里返回4)
// 4. fromIndex 超出字符串长度(等效于末尾查找)
int indexA3 = str.lastIndexOf('a', 20);
System.out.println("fromIndex=20 查找 'a' 的位置:" + indexA3); // 输出:8(最后一个 'a')
}
}
场景 4:实际应用:提取文件后缀名 / 文件名
需求:
给定文件路径字符串,通过
lastIndexOf() 提取文件名和后缀名(开发中常见场景)。代码实现:
public class FilePathParseDemo {
public static void main(String[] args) {
String filePath = "D:/document/project/java/StringDemo.java";
// 1. 提取文件名(最后一个 "/" 之后的内容)
int lastSlashIndex = filePath.lastIndexOf("/");
String fileName = filePath.substring(lastSlashIndex + 1);
System.out.println("文件名:" + fileName); // 输出:StringDemo.java
// 2. 提取后缀名(最后一个 "." 之后的内容)
int lastDotIndex = filePath.lastIndexOf(".");
if (lastDotIndex != -1) { // 确保存在后缀名
String suffix = filePath.substring(lastDotIndex + 1);
System.out.println("文件后缀名:" + suffix); // 输出:java
} else {
System.out.println("该文件无后缀名");
}
// 3. 处理 Windows 路径(反斜杠 "\\",需转义)
String windowsPath = "C:\\Users\\test\\photo.png";
int lastBackslashIndex = windowsPath.lastIndexOf("\\");
String windowsFileName = windowsPath.substring(lastBackslashIndex + 1);
System.out.println("Windows 路径文件名:" + windowsFileName); // 输出:photo.png
}
}
三、注意事项(避坑指南)
-
空值与空字符串处理:
- 传入
null作为子串(如str.lastIndexOf(null)):抛出NullPointerException,需提前判空。 - 传入空字符串
"":返回字符串长度(如"test".lastIndexOf("") → 4),这是 Java 的设计规则,无需特殊处理。
- 传入
-
区分大小写:
lastIndexOf()是大小写敏感的(如"Java".lastIndexOf("java") → -1)。- 若需忽略大小写,需先将原字符串和目标串统一转为大写或小写(如
str.toLowerCase().lastIndexOf("java"))。
-
索引越界问题:
- 提取子串时(如
substring()),需先判断lastIndexOf()返回值是否为-1(避免未找到目标时导致StringIndexOutOfBoundsException)。 - 示例:
// 错误写法(未判断 -1) String suffix = filePath.substring(filePath.lastIndexOf(".") + 1); // 无后缀时会报错 // 正确写法 int dotIndex = filePath.lastIndexOf("."); String suffix = dotIndex != -1 ? filePath.substring(dotIndex + 1) : "无后缀";
- 提取子串时(如
-
Unicode 字符查找:
lastIndexOf(int ch)中ch是 Unicode 编码,可直接传入字符(如'中')或对应的 Unicode 数值(如'\u4e2d')。- 示例:
"中国,中国".lastIndexOf('中') → 3(索引 0 和 3 均为 ' 中 ',返回最后一个)。
四、总结
lastIndexOf() 是 Java 处理字符串的核心方法,核心用途是从后向前查找字符 / 子串的位置,配合 substring() 可实现文件路径解析、后缀提取、数据清洗等实际需求。使用时需注意:- 未找到目标返回
-1,需提前判断避免索引越界; - 区分大小写,按需统一转换;
- 处理
null参数,避免空指针异常。
浙公网安备 33010602011771号