String.subString() 和 String.subSequence() 有啥区别

Posted

技术标签:

【中文标题】String.subString() 和 String.subSequence() 有啥区别【英文标题】:What is the difference between String.subString() and String.subSequence()String.subString() 和 String.subSequence() 有什么区别 【发布时间】:2013-03-08 11:34:59 【问题描述】:

String.subSequence() 具有以下 javadoc:

返回一个新的字符序列,它是 this 的子序列 顺序。

调用此方法的形式

str.subSequence(begin, end)

行为方式与调用完全相同

str.substring(begin, end) 

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

谁能解释一下?

【问题讨论】:

【参考方案1】:

要理解这一点,首先你需要知道的是substringsubsequence

有什么区别

子字符串连续部分或字符串的子部分

子序列是字符串或序列的一部分,可能是连续的或不连续的,但元素的顺序保持不变

例如,假设我们有以下字符串:

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 的子序列,因为在这种情况下 order不维护。

现在对于 java,javadoc 中没有关于这些方法的适当说明。

【讨论】:

【参考方案2】:

子序列

子序列是子字符串、后缀和前缀的概括。找到两个或多个字符串的子序列中的最长字符串称为最长公共子序列问题。

示例:字符串“anna”是字符串“banana”的子序列:

banana
 || ||
 an na

子字符串

字符串的子字符串是字符串后缀的前缀,也就是前缀的后缀。如果一个字符串是另一个字符串的子字符串,那么它也是一个子序列,这是一个更笼统的概念。

示例:字符串“ana”是香蕉在两个不同偏移量处的子字符串(和子序列):

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

阅读更多here。

但就 Java 而言,它们的使用没有任何区别,正如 javadoc 中明确说明的那样。同样正如其中所述,方法subSequence 仅在String 类中实现,以使其符合CharSequence 接口。 而且这个方法的名字确实是用词不当。

【讨论】:

这是我一直在寻找的答案。 这个答案解释了这个概念。但是你不能在 Java 中使用 .subSequence(begin, end) 方法从“banana”中得到“anna”。该问题的公认答案解释了两个输出将如何相似而仅在类型上有所不同。【参考方案3】:

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

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

只有在不实例化CharSequence 的新实例的情况下,您无法更改CharSequence 中的chars

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

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

并使用所有普通的String 运算符,例如subSequence += " World";

【讨论】:

与.subString() 相同。有什么区别? 它们是相同的。它只是一个返回CharSequence,另一个返回String。省去了在它们之间投射。正如它在 [javadoc](docs.oracle.com/javase/6/docs/api/java/lang/…, int)) 中所说,它的定义是为了让 String 类可以实现(和使用)CharSequence 接口。 @sam 上面的评论应该是答案。它会节省我通过那个答案的时间。【参考方案4】:

简单的理解:

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

Substring
string
ring

子序列:从一个字符串,任何字符,但顺序。

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

【讨论】:

【参考方案5】:

子串是连续的子序列。

例如,对于序列 abc 我们有

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

当字母重复时,一些子串和子序列看起来会一样。

【讨论】:

【参考方案6】:

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

【讨论】:

【参考方案7】:

简而言之,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实现了CharSequenceString继承了看似多余的方法。

【讨论】:

【参考方案8】:

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

【讨论】:

以上是关于String.subString() 和 String.subSequence() 有啥区别的主要内容,如果未能解决你的问题,请参考以下文章

使用正则表达式在 Java 中拆分嵌套 JSON

java String.substring 乱码

String.Substring() 似乎是这段代码的瓶颈

string.substring 与 string.take

C# String.Substring 等效于 StringBuilder?

为啥 string.Substring 不与源字符串共享内存?