String.subString()和String.subSequence()的区别是什么?

37

String.subSequence() 的Javadoc如下:

返回一个新的字符序列,该序列是此序列的子序列。

以以下形式调用此方法:

str.subSequence(begin, end)

表现出与调用完全相同的方式

str.substring(begin, end) 

这个方法的定义是为了让String类实现CharSequence接口。

9个回答

54
为了理解这一点,你需要知道的第一件事是子字符串(substring)子序列(subsequence)之间的区别。 子字符串是字符串的一个连续部分或子部分。
子序列是字符串或序列的一部分,可能是连续的,也可能不是,但元素的顺序是保持不变的。
举个例子,假设我们有以下字符串:
str_a="hello there"
str_b="hello"
str_c="ello th"
str_d="hllo"
str_e="ho hre"
str_f="there hello"

str_bstr_a的子字符串,str_c也是str_a的子字符串,但str_d不是str_a的子字符串,因为这个子字符串不是连续的。

现在所有的子字符串都是子序列,因为顺序被保留。

str_dstr_a的子序列,str_e也是str_a的子序列,但是str_f不是str_a的子序列,因为在这种情况下顺序没有得到保留。

现在对于Java而言,在javadoc中没有关于这些方法的适当澄清。


50

子序列

子序列是子串、后缀和前缀的一般化。查找两个或多个字符串的最长公共子序列是被称为最长公共子序列问题。

例如:字符串"anna"是字符串"banana"的子序列:

banana
 || ||
 an na

子字符串

一个字符串的子字符串是该字符串的前缀或后缀,并且同样也是一个前缀或后缀的子串。如果一个字符串是另一个字符串的子串,那么它也是一个更通用的子序列。

例如:字符串"ana"是香蕉的子字符串(和子序列),在不同的偏移位置上出现两次:

banana
 |||||
 ana||
   |||
   ana

阅读更多内容请点击这里

但就Java而言,正如在javadoc中明确说明的那样,在它们的使用上并没有任何区别。同时在其中所述的,方法subSequence已经在String类中实现,以使其符合CharSequence接口。 而这个方法的名称确实只是一个误称。


27

使用str.subSequence(begin, end)返回一个CharSequence,它是作为char序列表示的字符串的只读形式。例如:

String string = "Hello";
CharSequence subSequence = string.subSequence(0, 5);

从字面上看,“只读”是指你无法在不实例化新的CharSequence实例的情况下更改CharSequence中的字符。

如果您必须使用 str.subSequence(begin, end),您可以将结果强制转换为 String

String string = "Hello";
String subSequence = (String) string.subSequence(0, 5);

并使用所有常规的String运算符,如subSequence += " World";


13

简单易懂地说:

子字符串:子字符串是字符串中连续的一段字符序列,其中顺序很重要。

Substring
string
ring

子序列: 从一个字符串中,任意选择但需保持字符顺序。

Substring
u s i
s b t i n g
r g

2

子字符串是连续的子序列。

例如,对于序列abc,我们有:

substrings: a, ab, abc, b, bc, c, and the empty substring;
subsequences: a, b, ab, c, ac, bc, abc, and the empty subsequence.

当字母重复时,一些子字符串和子序列看起来是相同的。


0
简而言之,对于String对象来说,这并不重要。它们是等效的,除非您需要将结果传递给仅接受String的某些内容,在这种情况下,您必须使用subtring(int,int)版本或将subsequence(int,int)版本转换为String(因为在内部它就是这样)。 String.substring(int,int)首先存在,因为String首先存在。在Java 1.4中,添加了CharSequence,显然有人意识到在那里具有相同功能但返回CharSequence而不是String(以提高灵活性)将很有用。因此,CharSequence.subSequence(int,int)出现了。但是,由于String实现了CharSequence,所以String继承了这个看似多余的方法。

0

如果你查看String的源代码,你会发现subsequence实际上调用了substring。它唯一与substring不同的是将字符串强制转换为CharSequence。


0

我的回答是针对代码的;为了更好理解。

让我们从“序列”和“子序列”的含义开始。

序列

  • 序列是一组物品的列表,其中物品的顺序很重要。

  • 例如,字符串GACA包含多个相同字符(A),并且与具有相同字符集的字符串CAAG不同。

子序列

  • 字符串X的子序列Z是X,可能删除了一些项。

  • 例如,如果X是字符串GAC,则它有八个子序列:

    1:GAC(没有删除字符)

    2:GA(删除C),

    3:GC(删除A),

    4:AC(删除G),

    5:G(删除A和C),

    6:A(删除G和C),

    7:C(删除G和A),以及

    8:空字符串(删除所有字符)。

  • 例如,如果X是字符串CATCGA,Y是字符串GTACCGTCA,则CCA是由三个字符组成的X和Y的公共子序列。

注意1:它不是最长公共子序列(LCS),因为公共子序列CTCA有四个字符。

注意2:CTCA是最长公共子序列,但它不是唯一的,因为TCGA是另一个具有四个字符的公共子序列。

子字符串

  • 子字符串是一个字符串的子序列,其中字符必须来自于字符串中连续的位置。
  • 例如,在字符串CATCGA中,子序列ATCG是一个子字符串,但子序列CTCA不是。

-1

基本上就是返回什么,一个是字符串,另一个是CharSequence(你可以将其强制转换为字符串)。
当你需要一个CharSequence类型的变量时,你会使用subSequence。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接