像Java API方法:为什么从索引是包含但结束索引是排他性的?
String.substring(int beginIndex, int endIndex)
String.subSequence(int beginIndex, int endIndex)
List.subList(int fromIndex, int toIndex)
为什么开始指数包括但最终指数独占?为什么它们不应该被设计成兼而包括?
像Java API方法:为什么从索引是包含但结束索引是排他性的?
String.substring(int beginIndex, int endIndex)
String.subSequence(int beginIndex, int endIndex)
List.subList(int fromIndex, int toIndex)
为什么开始指数包括但最终指数独占?为什么它们不应该被设计成兼而包括?
因为:
object.length
(但对象实现此,例如,大小()等)到toIndex参数 - 无需加/减1例如:
String lastThree = str.substring(str.length() - 3, str.length());
这样,代码中发生了什么非常明显(好东西)。
EDIT C函数行为类似这个的一个例子是strncat
从string.h
:
char *strncat(char *dest, const char *src, size_t n);
的size_t
参数的值对应于在Java endPosition
参数,因为它们两者的所述长度对象,但是从0开始计数,如果它们是索引,则它将是一个字节超出对象的末尾。
问题是他们没有使用C/C++语法。 我认为C语法更具可读性。例如,如果你想利用与lenght 2子串从列表X的第三个元素开始,你写
X.subList(2,3).
在Java中,如果你想采取一个子列表,只有列表X的第三元素,你需要写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胜;在任何情况下都更具可读性,可惜他们改变了这一点。但这只是一个额外的评论,你可以ingore。
这就是所谓的的Dijkstra约定范围[i, j>
(或其他数学符号[i, j)
的。这样你可以处理的范围[a, b>, [b, c>, [c, d]
。
有人认为,这是较为有效的,而事实上我们程序员使用它:
for (int i = 0; i < n; ++i) { ... }
在这样的范围内的元素的数目是j - i
,所以是一个-1/+ 1保存
它也用于BitSet.set(from, to)
+1第二个原因 – 2011-06-14 04:52:34
哪个C函数这样做? – 2011-06-14 06:31:42
不正确的是C/C++中的substr可以用作Java。 C中的substr将长度作为第二个参数,因此substr(3,2)表示“从带索引3的字符开始取2个字符”。 我认为C语法更具可读性。 – fresko 2017-11-28 11:38:04