在Java API方法中,例如:
String.substring(int beginIndex, int endIndex)
String.subSequence(int beginIndex, int endIndex)
List.subList(int fromIndex, int toIndex)
为什么起始索引包含但最终索引是独占的?为什么他们不应该被设计为包容性的?
答案 0 :(得分:17)
由于:
object.length
(但是对象实现了这个,例如size()等)到toIndex参数 - 不需要添加/减去1 例如:
String lastThree = str.substring(str.length() - 3, str.length());
这样,很明显代码中发生的事情(一件好事)。
编辑此行为的C函数示例是来自strncat
的{{1}}:
string.h
char *strncat(char *dest, const char *src, size_t n);
参数的值对应于java size_t
参数,因为它们都是对象的 length ,但如果它们是,则从0开始计数index ,它将是超出对象结尾的一个字节。
答案 1 :(得分:0)
问题是他们没有使用C / C ++语法。 我认为C语法更具可读性。例如,如果你想从列表X的第3个元素开始获取长度为2的子字符串,你可以编写
X.subList(2,3).
在Java中,如果要仅使用List X的第3个元素获取子列表,则需要编写X.subList(2,3)。 这真的很难看,你似乎正在采用2个元素的子列表。另一方面,X.subList(2,2)是一个空列表 - 非常令人困惑。
int startIndex = calculateStartIndex();
int endIndex = calculateEndIndex();
X.subList(startIndex, endIndex);
实际上,如果(startIndex == endIndex)→空列表。
你的问题是:为什么,所以这是我的答案。 如果Java中的两个参数都是包容性的,会发生什么?当你计算第二个索引时需要取一个空列表时会遇到问题。因为在大多数情况下会计算索引,我们不会直接在函数中写入数字。
为了得到一个空列表,除非你使用一个惯例(例如:在负或低endIndex返回空列表的情况下) - 但这样的召唤可以隐藏编码中的错误(如果第二个参数是 - 没有区别 - 1或-100!):
int startIndex = calculateStartIndex(); // return 0
int endIndex = calculateEndIndex(); // return 0
X.subList(startIndex, endIndex); // this would return the 1st element of the list; how to get an empty list? Convenction needed!
// use a negative number to get empty list? And what if endIndex is negative because of a bug?
我是这样的,C胜;在任何情况下都更具可读性,可惜他们改变了这一点。但这只是你可以提出的另一个评论。
答案 2 :(得分:0)
它被称为范围<div id="TextBoxDiv1">
<label>Textbox #1 : </label>
<input type="text" id="textbox1" name="textbox1" class="required">
</div>
的 Dijkstra 惯例(或其他数学符号[i, j>
。通过这种方式,您可以处理范围[i, j)
。< / p>
有人认为它更有效率,事实上我们程序员在以下方面使用它:
[a, b>, [b, c>, [c, d]
在这样的范围内,元素的数量是for (int i = 0; i < n; ++i) { ... }
,所以是保存-1 / + 1。
它也用于j - i
答案 3 :(得分:-1)
除了波希米亚所说的:
如果它是独占的,要获得字符串中的第一个4
字符,您必须:
String firstFour = String.substring(0, 3);
那很难看。