因此,在Java中,每当给出索引范围时,上限几乎总是排他的。
来自java.lang.String:
java.lang.String
substring(int beginIndex, int endIndex) 返回一个新字符串,该字符串是该字符串的子字符串。子字符串从指定的字符串开始,beginIndex并扩展到索引的字符endIndex - 1
substring(int beginIndex, int endIndex)
返回一个新字符串,该字符串是该字符串的子字符串。子字符串从指定的字符串开始,beginIndex并扩展到索引的字符endIndex - 1
beginIndex
endIndex - 1
来自java.util.Arrays:
java.util.Arrays
copyOfRange(T[] original, int from, int to) from-要复制的范围的初始索引(包括两端) to- 要复制的范围的最终索引,包括高端。
copyOfRange(T[] original, int from, int to)
from-要复制的范围的初始索引(包括两端) to- 要复制的范围的最终索引,包括高端。
from
to
来自java.util.BitSet:
java.util.BitSet
set(int fromIndex, int toIndex) fromIndex-要设置的第一位的索引。 toIndex-要设置的最后一位之后的索引。
set(int fromIndex, int toIndex)
fromIndex-要设置的第一位的索引。 toIndex-要设置的最后一位之后的索引。
fromIndex
toIndex
如您所见,它看起来确实像Java试图使它成为一致的约定,即上限是互斥的。
我的问题是:
澄清:我完全理解N基于0的系统中的对象集合已建立索引0..N-1。我的问题是,如果(2,4)给定范围,则可以是3个项目或2个项目,具体取决于系统。您如何称呼这些系统?
N
0..N-1
(2,4)
再次,问题不是“第一索引0最后索引N-1”与“第一索引1最后索引N”系统;即基于0的系统与基于1的系统。
0
N-1
1
问题是“系统中有3个元素,而(2,4)vs (2,4)系统中有2个元素。您怎么称呼这些,其中一个受到正式制裁?
归功于FredOverflow在他的评论中说,这被称为“半开区间”。因此,大概可以将Java集合描述为“ 基于0的半开放范围 ”。
我已经在其他地方整理了一些关于半开和封闭范围的讨论:
Siliconbrain.com- 使用半开范围的16个充分理由(为简洁起见进行了编辑):
范围内的元素数目[n, m)只是m-n(和不m-n+1)。 空范围是[n, n)(而不是[n, n-1],如果n迭代器已经指向列表的第一个元素,或者if ,则可能是一个问题n == 0)。 对于浮点数,您可以编写[13, 42)(而不是[13, 41.999999999999])。 当处理范围时,+1和-1几乎从未使用过。如果它们很昂贵(如日期),则这是一个优势。 如果您在范围内编写查找,则可以通过将末尾作为查找位置返回来轻松表明未找到任何事实:未找到if( find( [begin, end) ) == end)任何内容。 在以0开头的数组下标的语言(例如C,C ++,JAVA,NCL)中,上限等于大小。
[n, m)
m-n
m-n+1
[n, n)
[n, n-1]
n
n == 0
[13, 42)
[13, 41.999999999999]
+1
-1
if( find( [begin, end) ) == end)
半开与封闭范围
半开范围的优势: 空范围有效: [0 .. 0] 子范围很容易转到原始内容的末尾: [x .. $] 易于分割范围:[0 .. x]和[x .. $] 近距离射程的优势: 对称。 可以说更容易阅读。 ['a' ... 'z']``+ 1之后不需要尴尬'z'。 [0 ... uint.max] 是可能的。
半开范围的优势:
[0 .. 0]
[x .. $]
[0 .. x]
近距离射程的优势:
['a' ... 'z']``+ 1
'z'
[0 ... uint.max]
最后一点很有趣。numberIsInRange(int n, int min, int max)如果Integer.MAX_VALUE可以合法地在范围内,则写一个半开范围的谓词确实很尴尬。
numberIsInRange(int n, int min, int max)
Integer.MAX_VALUE