为什么substring()方法substring(起始索引(包括),结束索引(独占))

shi*_*njw 5 java string

substring将起始参数作为索引,第二个参数作为从头开始的长度的原因是什么?

换一种说法

1   2   3 | 4   5 <=== Length from beginning

A   B   C   D   E

0 | 1   2   3   4 <=== Index
Run Code Online (Sandbox Code Playgroud)

如果我想要substring()返回BC我必须做"ABCDE".substring(1,3);

为什么会这样?

编辑:使结束索引独占有什么好处?

Mar*_*o13 8

关于"为什么"的问题可以被认为是哲学的或学术的,并且沿着"那就是它的方式"的方式挑起答案.

然而,从更一般的抽象观点来看,在考虑替代方案时,这是一个有效的问题:人们可以想象这种方法的两种形式:

String substringByIndices(int startIndex, int endIndex);
Run Code Online (Sandbox Code Playgroud)

String substringByLength(int startIndex, int length);
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,设计空间还有另一个方面,即指数是包容性的还是排他性的.

首先,请注意所有版本基本相同.在调用站点,根据方法的实际语义更改调用​​通常是微不足道的:

int startIndex = ...;
int endIndex = ...;
String s = string.substringByLength(startIndex, endIndex-startIndex);
Run Code Online (Sandbox Code Playgroud)

要么

int startIndex = ...;
int length = ...;
String s = string.substringByIndices(startIndex, startIndex+length);
Run Code Online (Sandbox Code Playgroud)

选择指数是包容性还是排他性将增加一些潜在的不得不摆弄+1-1在这里和那里,但这在这里并不重要.

第二个例子已经说明了为什么选择使用包含起始索引和独占结束索引可能是一个好主意:很容易切出一定长度的子字符串,而不必考虑任何+1-1:

int startIndex = 12;
int length = 34;
String s = string.substringByIndices(startIndex, startIndex+length);

// One would expect this to yield "true". If the end index
// was inclusive, this would not be the case...
System.out.println(s.length() == length); 
Run Code Online (Sandbox Code Playgroud)

这也可能被认为与for-loops之类的东西一致,你通常拥有它

for (int i=startIndex; i<endIndex; i++) { ... }
Run Code Online (Sandbox Code Playgroud)

开始是包容性的,结束是独家的.因此,这种选择很好地与通常的惯用语言模式相匹配.


但是,无论做出哪种选择,无论其如何合理:重要的是

一贯

贯穿整个API.

例如,List接口包含方法subList(int,int):

List<E> subList(int fromIndex, int toIndex)
Run Code Online (Sandbox Code Playgroud)

返回指定fromIndex(包含)和toIndex(独占)之间此列表部分的视图.

符合这一惯例.如果你必须混合API,其中结束索引有时是包容性的,有时是独占的,这将是容易出错的.


Stu*_*ion 5

这是一个开始和结束索引。

对我来说这似乎很合乎逻辑,但是如果您愿意,可以使用非常简单的计算从开始和长度的角度考虑它:

"ABCDEFGH".substring(start, start + length);
Run Code Online (Sandbox Code Playgroud)

它为您提供了这种灵活性。