User Lihu Zhai
Lihu Zhai
Software Architect 位于 Ruijie Networks

Java 中的子字符串

已在 China 群组中发布
在 Java 中 String 的常见操作是串联,通过下标获取字符,进而得到一个子字符串。在本文中,我们将讲解有关 Java 子字符串方法的内容。

Java 中的子字符串是什么?

子字符串通常是 String 中连续的字符序列。它可能是 String 一部分,也可能是整个 String。 Java 中的子字符串 - 1Java 中的子字符串是什么?此语言提供一个 substring() 方法,而不是两个方法,这是因为 Java 方法具有重载功能。你可以使用这些方法在 Java 程序中获取子字符串。第一个 Java 子字符串方法是 String substring(firstIndex),而第二个子字符串方法是 String substring (firstIndex, lastIndex)

如何在 Java 中使用子字符串

答案很简单:只需使用 substring 即可。Java substring() 方法返回部分字符串。有两个方法可用于此目的:
子字符串方法的语法 String substring(firstIndex) String substring (firstIndex, lastIndex)
参数 firstIndex 是 String 中的编号,这是子字符串的第一个下标(含)。Substring 的最后一个编号是整个字符串的最后一个编号 firstIndex 是 String 中的编号,这是子字符串的第一个下标(含)。
lastIndex 是 String 中的编号,此编号之后的第一个和所有编号都排除在子字符串外
如何在 Java 中使用子字符串的示例

String s = "CodeGym";
System.out.println(s.substring(4));
//返回 Gym

String s = "CodeGym";
System.out.println(s.substring(2,5));
//返回 deG
很常见的任务,对你理解子字符串有所帮助
  • 如何在 Java 中获取子字符串
  • 如何在给定子字符串中查找所有子字符串
  • 如何查找最长公共子字符串

如何在 Java 中获取子字符串(特定)

第一个 Java 子字符串示例非常简单。您获得一个 String,而且你需要在其中查找子字符串“CodeGym”。你已经了解如何在 Java 中获取子字符串。这里提供此特定问题的解决方法:

import java.io.IOException;

public class Main {

   public static void main(String[] args) throws IOException {

       String s1 = "最好的 Java 核心课程是 CourseCodeGym。故事结束";
       String myTarget = "CodeGym";
       int index1 = s1.indexOf(myTarget);

       int index2 = index1 + myTarget.length();
       System.out.println(s1.substring(index1, index2));

   }
}
输出是:
CodeGym Process finished with exit code 0
Java 中的子字符串 - 2

如何查找给定字符串的所有子字符串

这里我们采用最简单的方法来查找给定 String 的所有子字符串。

import java.io.IOException;
public class Main {
   public static void main(String[] args) throws IOException {
       String myTarget = "CodeGym";
       for (int i = 0; i < myTarget.length(); i++) {
           for (int j = i + 1; j <= myTarget.length(); j++) {
               System.out.println(myTarget.substring(i, j));
           }
       }
   }
}
输出是:
C Co Cod Code CodeG CodeGy CodeGym o od ode odeG odeGy odeGym d de deG deGy deGym e eG eGy eGym G Gy Gym y ym m Process finished with exit code 0

如何查找最长公共子字符串

最长公共子字符串问题是计算机科学中最常见的任务之一。你很有可能在初级开发人员的面试中遇到这个任务。无论如何,尝试解决,这对初学者而言都是个非常有用的练习。 最长公共子字符串问题是指查找最长的字符串(或几个字符串),该字符串是两个或多个字符串的一个或多个子字符串。例如,你有两个字符串

String first = "CodeGym"
String second = "SomeGym"
输入应为:
eGym
因此,你应在字符串“first”和“second”中查找。输入最长公共子字符串如果两个或多个子字符串的最长公共子字符串具有相同的值,则打印其中任何一个。 我们强烈建议你尝试自行解决这个问题,然后再查看下面的代码。

public class SubStringTest {

   // 在此方法中,我们寻找长度为 m 的第一个 String
   // 和长度为 n 的第二个 String 的公共子字符串
   public static String longestCS(String first, String second, int m, int n) {
       // 最大长度
       int maxLength = 0;
       // 最长公共子字符串的最后一个下标
       int endIndex = m;

       // 数组存储子字符串的长度
       int[][] keeper = new int[m + 1][n + 1];

       for (int i = 1; i <= m; i++) {
           for (int j = 1; j <= n; j++) {
               // 检查第一个和第二个字符串的当前字符是否匹配
               if (first.charAt(i - 1) == second.charAt(j - 1)) {
                   keeper[i][j] = keeper[i - 1][j - 1] + 1;

                   if (keeper[i][j] > maxLength) {
                       maxLength = keeper[i][j];
                       endIndex = i;
                   }
               }
           }
       }
       return first.substring(endIndex - maxLength, endIndex);
   }


   public static void main(String[] args) {
       String first = "CodeGym";
       String second = "SomeGym";
       int m = first.length(), n = second.length();
       System.out.println("最长公共子字符串 = " + longestCS(first, second, m, n));
   }
}
输出是:
最长公共子字符串 = eGym

在 Java 中子字符串是如何工作的

在 JDK 7 和更高版本中,substring() 不再像 JDK 6 之前的版本那样计算它创建的字符数组中的字符数,而是只在内存(堆)中创建新数组并引用它。下面是一个示例:

String x = "CodeGymIsTheBest";
String y = x.substring (2,6);
String z = x.substring (0,3);
因此,在 JDK 7 和更高版本中,yz(由 substring() 方法应用于对象 x 而创建的)将参考两个新创建的数组(在堆中国)- 对 y{d, e, G, y},对 z{C, o}。 在 JDK 7 + 版本的方法 substring 中,这两个新行(即两个新的字符数组)将与原始字符串 myLongString(以数组 {C, o, d, e, G, y, m, i, s, t, h, e, b, e, s, t} 的形式) 一起存储在内存中。

JDK 6 版本的子字符串

即使在今天的一些大型项目中,你可能会遇到 JDK 6 时代的遗留代码库。在 JDK 6 中,方法 substring() 的工作方式有所不同。 您可能知道,String 是一个不可变的 Class,要获取子字符串,Java 使用了 JDK 6 早期的这种不可变性。String 类型对象的内部是一个字符数组,而不是包含一个字符数组。在 JDK 6 的时代,这里又存储了两个变量:字符数组中第一个字符的编号和它们的数量。因此,在 JDK 6 中,String 包含三个字段:char value [](字符数组)、int offset(数组中第一个字符的下标)和 int count(数组中字符的编号)。 当在 JDK 6 中创建子字符串时,字符的数组不会复制到新 String 对象中。与之不同的是,这两个对象都会存储对相同字符数组的引用。然而,第二个对象存储了两个变量,第一个是子字符串的符号,第二个是子字符串中有多少个符号。 由于内存泄漏问题,JDK 6 方法被替换。这是什么意思呢?假定我们有一个字符串 x,我们使用 substring 创建了一些子字符串。

String x = "CodeGymIsTheBest";
String y = x.substring (2,6);
String z = x.substring (0,3);
现在,我们的对象 x 存储在内存中称为堆的特殊区域,两个对象 yz 引用了相同的对象 x。只有 x 引用从第二个到第六个元素,而 z 引用从第 0 个到第三个 x 元素。如果原始对象 x 已被使用并且其上没有任何引用该怎么办?在某个程序中,所有其他对象都只处理 yz。 垃圾回收器可能会销毁对象 x,而内存数组仍然保留,并由 y 和 z 使用。这就造成内存泄露发生了。 因此,新版 JDK 7 和更高版本,方法在内存使用方面成本高昂。不过这可让你防止内存泄露。此外,新方法工作速度更快,它不会计算字符的数量。

更多阅读内容:

评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION