杰瑞科技汇

Java substring 截取时,索引越界怎么办?

substring 方法用于从字符串中提取一个子字符串(即原字符串的一部分),Java 中主要有两种形式的 substring 方法,它们位于 String 类和 StringBuilder/StringBuffer 类中。

Java substring 截取时,索引越界怎么办?-图1
(图片来源网络,侵删)

String 类中的 substring 方法

这是最常用的情况,用于从一个不可变的字符串 String 中创建一个新的子字符串。

substring(int beginIndex)

这个方法从指定的 beginIndex 索引处开始,截取到字符串的末尾。

语法:

public String substring(int beginIndex)

参数:

Java substring 截取时,索引越界怎么办?-图2
(图片来源网络,侵删)
  • beginIndex:开始截取的索引(包含),索引从 0 开始。

返回值:

  • 一个新的 String 对象,包含从 beginIndex 到原字符串末尾的所有字符。

示例:

public class SubstringExample1 {
    public static void main(String[] args) {
        String str = "Hello, World!";
        // 从索引 7 开始截取
        String subStr = str.substring(7);
        System.out.println("原始字符串: " + str); // 输出: Hello, World!
        System.out.println("截取后的字符串: " + subStr); // 输出: World!
    }
}

substring(int beginIndex, int endIndex)

这个方法从指定的 beginIndex 索引处开始,截取到 endIndex 索引处之前结束。注意:endIndex 索引处的字符不包含在结果中。

语法:

Java substring 截取时,索引越界怎么办?-图3
(图片来源网络,侵删)
public String substring(int beginIndex, int endIndex)

参数:

  • beginIndex:开始截取的索引(包含)。
  • endIndex:结束截取的索引(不包含)。

返回值:

  • 一个新的 String 对象,包含从 beginIndexendIndex-1 的所有字符。

示例:

public class SubstringExample2 {
    public static void main(String[] args) {
        String str = "Hello, World!";
        // 从索引 7 开始,截取到索引 12 之前
        String subStr = str.substring(7, 12);
        System.out.println("原始字符串: " + str); // 输出: Hello, World!
        System.out.println("截取后的字符串: " + subStr); // 输出: World
    }
}

StringBuilderStringBuffer 中的 substring 方法

StringBuilderStringBuffer 是可变的字符序列,它们也提供了 substring 方法,但行为略有不同。

方法:substring(int beginIndex)substring(int beginIndex, int endIndex)

这两个方法的功能与 String 类中的同名方法类似,但返回值类型是 CharSequence,而不是 String

语法:

public CharSequence substring(int beginIndex)
public CharSequence substring(int beginIndex, int endIndex)

返回值:

  • 一个 CharSequence 对象,它代表了子字符串序列。

如何使用: 我们会将返回的 CharSequence 转换为 String 来使用。

示例:

public class StringBuilderSubstringExample {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder("Hello, Java!");
        // 使用 substring 方法
        CharSequence cs1 = sb.substring(7); // 返回 CharSequence
        CharSequence cs2 = sb.substring(7, 11); // 返回 CharSequence
        // 将 CharSequence 转换为 String
        String subStr1 = cs1.toString();
        String subStr2 = cs2.toString();
        System.out.println("原始 StringBuilder: " + sb); // 输出: Hello, Java!
        System.out.println("截取后的 CharSequence: " + cs1); // 输出: Java!
        System.out.println("转换为 String 后: " + subStr1); // 输出: Java!
        System.out.println("指定范围的截取: " + subStr2); // 输出: Java
    }
}

重要注意事项

索引越界异常 (StringIndexOutOfBoundsException)

这是使用 substring 时最常见的错误,如果提供的索引值不合法,程序就会抛出 StringIndexOutOfBoundsException

不合法的索引包括:

  • beginIndexendIndex 为负数。
  • beginIndex 大于字符串的长度 (str.length())。
  • endIndex 大于字符串的长度 (str.length())。
  • beginIndex 大于 endIndex

示例:

String str = "Hello";
// str.substring(-1); // 抛出异常
// str.substring(5);   // 正常,结果是空字符串 ""
// str.substring(6);   // 抛出异常
// str.substring(1, 5); // 正常
// str.substring(1, 6); // 抛出异常
// str.substring(3, 2); // 抛出异常

beginIndexendIndex 的范围

  • beginIndex 的有效范围是 [0, str.length()]
  • endIndex 的有效范围是 [0, str.length()]
  • beginIndex 等于 str.length(),结果将是一个空字符串 。
  • beginIndex 等于 endIndex,结果也将是一个空字符串 。

字符串不可变性

String 对象是不可变的。substring 方法不会修改原始字符串,而是创建并返回一个新的 String 对象

示例:

String original = "I am a String";
String modified = original.substring(5, 7);
System.out.println("原始字符串: " + original); // 输出: I am a String
System.out.println("新字符串: " + modified);   // 输出: a
System.out.println("original 是否等于 modified? " + (original == modified)); // 输出: false

Java 8 新增:subSequence(int beginIndex, int endIndex)

Java 8 在 String 类中新增了 subSequence 方法,它的功能与 substring(int beginIndex, int endIndex) 完全相同,只是返回类型是 CharSequence

public CharSequence subSequence(int beginIndex, int endIndex)

使用场景: 当你需要一个通用的字符序列接口 CharSequence 而不是具体的 String 类型时,可以使用这个方法,这通常用于更通用的 API 设计中。

示例:

String str = "Hello, World!";
CharSequence cs = str.subSequence(7, 12);
System.out.println(cs.toString()); // 输出: World

总结与最佳实践

方法 所在类 功能 返回类型 示例
substring(int beginIndex) String beginIndex 截取到末尾 String str.substring(7) -> "World!"
substring(int beginIndex, int endIndex) String beginIndex 截取到 endIndex 之前 String str.substring(7, 12) -> "World"
substring(int beginIndex) StringBuilder beginIndex 截取到末尾 CharSequence sb.substring(7).toString() -> "Java!"
substring(int beginIndex, int endIndex) StringBuilder beginIndex 截取到 endIndex 之前 CharSequence sb.substring(7, 11).toString() -> "Java"
subSequence(int beginIndex, int endIndex) String beginIndex 截取到 endIndex 之前 CharSequence str.subSequence(7, 12).toString() -> "World"

最佳实践:

  1. 对于 String 对象,优先使用 substring(int beginIndex, int endIndex),因为它可以精确控制截取的范围。
  2. 始终检查索引的有效性,或者使用 try-catch 块来捕获 StringIndexOutOfBoundsException,避免程序意外终止。
  3. String 是不可变的substring 操作会创建新对象,在需要频繁修改字符串内容的场景下,应考虑使用 StringBuilderStringBuffer
  4. 如果你的代码设计依赖于 CharSequence 接口,StringBuilder.substring()String.subSequence() 会是更好的选择。
分享:
扫描分享到社交APP
上一篇
下一篇