索引范围的上限始终假定为独占?

所以在Java中,无论何时给出索引范围,上限几乎总是独占的。

来自java.lang.String

substring(int beginIndex, int endIndex)

返回一个新字符串,该字符串是此字符串的子字符串。 子字符串从指定的beginIndex开始,并扩展到索引endIndex - 1处的字符

来自java.util.Arrays

copyOfRange(T[] original, int from, int to)

from – 要复制的范围的初始索引(包括)
to – 要复制的范围的最终索引,不包括。

来自java.util.BitSet

set(int fromIndex, int toIndex)

fromIndex – 要设置的第一个位的索引。
toIndex – 要设置的最后一位之后的索引。

正如您所看到的,它看起来像Java试图使其成为上限是独占的一致约定。

我的问题是:

  • 这是官方权威推荐吗?
  • 是否存在我们应该警惕的明显违规行为?
  • 这个系统有名字吗? (ala“0-based”vs“1-based”)

澄清:我完全理解基于0的系统中的N对象的集合被索引为0..N-1 。 我的问题是,如果给定范围(2,4) ,它可以是3项或2,具体取决于系统。 你怎么称呼这些系统?

再次,问题不是“第一指数0最后指数N-1 ”与“第一指数1最后指数N ”系统; 这就是所谓的基于0和基于1的系统。

问题是“ (2,4) ”中有3个元素与“ (2,4) ”系统中有2个元素。 你怎么称呼这些,并且正式批准另一个?

一般来说,是的。 如果您使用的是具有类C语法(C,C ++,Java)的语言,那么数组是零索引的,并且大多数随机访问数据结构(向量,数组列表等)将被归零同样。

将索引从零开始意味着数据结构的大小总是比数据结构中的最后一个有效索引大一。 当然,人们通常想知道事物的大小,因此谈论大小比谈论最后一个有效索引更方便。 人们习惯于以独占方式讨论结束索引,因为n元素long的数组a[]a[n-1]具有最后一个有效元素。

对结束索引使用独占索引还有另一个好处,即您可以通过从独占结束索引中减去包含性起始索引来计算子列表的大小。 如果我调用myList.sublist(3, 7) ,那么我会得到一个包含7 - 3 = 4元素的子列表。 如果sublist()方法已经为列表的两端使用了包含索引,那么我需要添加一个额外的1来计算子列表的大小。

当起始索引是一个变量时,这是特别方便的:从5个元素长的i开始获取myList的子列表只是myList.sublist(i, i + 5)

所有这些,你应该总是阅读API文档,而不是假设给定的开始索引或结束索引将是包容性的或排他性的。 同样,您应该记录自己的代码,以指示是否包含任何边界或独占。

它仅为0到n-1

列表/数组包含10个项目0-9索引。

你不能有一个0索引的列表,它是0-n,其中cout是n,包括一个不存在的项目…

这是典型的工作方式。

  1. 是的
  2. Excel范围/表格/工作簿。
  3. 指数(信息技术)

在评论中称FredOverflow称这是“半开放范围”。 因此,大概可以将Java Collections描述为“ 基于0的半开放范围 ”。

我在其他地方编写了一些关于半开放与封闭范围的讨论:


siliconbrain.com – 使用半开放范围的16个充分理由 (为简洁而编辑):

  • 范围[n, m)的元素数量仅为mn (而不是m-n+1 )。
  • 空范围是[n, n) (而不是[n, n-1] ,如果n是已经指向列表的第一个元素的迭代器,或者如果n == 0 ),则可能会出现问题。
  • 对于花车你可以写[13, 42) [13, 41.999999999999] (而不是[13, 41.999999999999] )。
  • 处理范围时,几乎从不使用+1-1 。 如果它们很昂贵(就像日期一样),这是一个优势。
  • 如果你在一个范围内写一个find,那么找不到任何东西的事实很容易通过将结尾作为找到的位置返回来表示: if( find( [begin, end) ) == end)找不到任何东西。
  • 在语言中,使用0开始数组下标(如C,C ++,JAVA,NCL),上限等于大小。

半开放与封闭范围

半开放范围的优点:

  • 空范围有效: [0 .. 0]
  • 子范围很容易转到原文的末尾: [x .. $]
  • 易于分割范围: [0 .. x][x .. $]

封闭范围的优点:

  • 对称。
  • 可以说更容易阅读。
  • ['a' ... 'z']'z'之后不需要笨拙+ 1
  • [0 ... uint.max]是可能的。

最后一点非常有趣。 如果Integer.MAX_VALUE合法地在一个范围内,那么用半开放范围写一个numberIsInRange(int n, int min, int max)谓词真的很尴尬。

这种做法由Josh Bloch作为合同引入Collections API。

之后它成了java的标准,当有人创建公共图书馆时,他认为他应该保留合同,因为用户希望看到新图书馆中已知的行为。

像数据结构这样的数组中的索引确实总是从0开始。 String基本上由char[] 。 Collections框架基于数组等等。 这使得设计/维护/使用API​​更容易,而无需改变“引擎盖下”方式来访问arrays中的所需元素。

但是有一些“例外”,例如PreparedStatement的基于parameterindex的setter方法和ResultSet的基于columnindex的getter方法。 他们是1基础。 在幕后,他们也没有真正代表一系列价值观。

这可能会提出一个新问题:“为什么数组索引为零?”。 现在,我们受人尊敬的计算机编程科学家EW Dijkstra 在此解释了为什么它应该从零开始。

考虑半开范围的简单方法是:第一项标识范围内元素的开始,第二项标识范围后元素的开始。 记住这一点,这一切都更有意义。 根据@polygenelubricants的回答,在许多情况下,算法效果更好。