【发布时间】:2011-06-14 04:43:42
【问题描述】:
在 Java API 方法中,例如:
String.substring(int beginIndex, int endIndex)String.subSequence(int beginIndex, int endIndex)List.subList(int fromIndex, int toIndex)
为什么开始索引包含但结束索引不包含?为什么它们不应该被设计成包容性的?
【问题讨论】:
标签: java
在 Java API 方法中,例如:
String.substring(int beginIndex, int endIndex)String.subSequence(int beginIndex, int endIndex)List.subList(int fromIndex, int toIndex)为什么开始索引包含但结束索引不包含?为什么它们不应该被设计成包容性的?
【问题讨论】:
标签: java
因为:
object.length(但是对象实现了这一点,例如 size() 等)传递到 toIndex 参数 - 无需添加/减去 1李>
例如:
String lastThree = str.substring(str.length() - 3, str.length());
这样一来,代码中发生的事情就非常明显了(一件好事)。
EDIT 一个类似这样行为的 C 函数示例是来自 string.h 的 strncat:
char *strncat(char *dest, const char *src, size_t n);
size_t 参数的值对应于 java 的 endPosition 参数,因为它们都是对象的 length,但如果它们是 index,则从 0 开始计数>,它将是一个字节超出对象的结尾。
【讨论】:
这称为范围[i, j>(或其他数学符号[i, j))的Dijkstra约定。通过这种方式,您可以处理范围[a, b>, [b, c>, [c, d]。
有人认为它更有效,实际上我们程序员使用它:
for (int i = 0; i < n; ++i) { ... }
在这样的范围内,元素的数量是j - i,所以是的,-1/+1 被保存了。
也用于BitSet.set(from, to)
【讨论】:
问题是他们没有使用 C/C++ 语法。 我认为 C 语法更具可读性。例如,如果您想从 List X 的第 3 个元素开始获取长度为 2 的子字符串,则编写
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);
其实 if (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 获胜;在任何情况下都更具可读性,可惜他们改变了这一点。但这只是您可以忽略的附加评论。
【讨论】:
除了波西米亚说的:
如果它是独占的,要获取字符串中的第一个 4 字符,您必须:
String firstFour = String.substring(0, 3);
那是相当丑陋的。
【讨论】:
substring(0,3)吗?