【问题标题】:why from index is inclusive but end index is exclusive?为什么 from index 包含但 end index 是独占的?
【发布时间】: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


    【解决方案1】:

    因为:

    • Java 是基于 C 的,而 C 是这样做的
    • 它使代码更清晰:如果你想捕获到对象的末尾,请将object.length(但是对象实现了这一点,例如 size() 等)传递到 toIndex 参数 - 无需添加/减去 1李>

    例如:

    String lastThree = str.substring(str.length() - 3, str.length());
    

    这样一来,代码中发生的事情就非常明显了(一件好事)。

    EDIT 一个类似这样行为的 C 函数示例是来自 string.hstrncat

    char *strncat(char *dest, const char *src, size_t n);
    

    size_t 参数的值对应于 java 的 endPosition 参数,因为它们都是对象的 length,但如果它们是 index,则从 0 开始计数>,它将是一个字节超出对象的结尾。

    【讨论】:

    • 哪个 C 函数是这样做的?
    • C/C++ 中的 substr 不能像 Java 一样工作。 C 中的 substr 将长度作为第二个参数,因此 substr(3,2) 表示“从索引为 3 的字符开始取 2 个字符”。我认为 C 语法更具可读性。
    【解决方案2】:

    这称为范围[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)

    【讨论】:

      【解决方案3】:

      问题是他们没有使用 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】:

        除了波西米亚说的:

        如果它是独占的,要获取字符串中的第一个 4 字符,您必须:

        String firstFour = String.substring(0, 3);

        那是相当丑陋的。

        【讨论】:

        • OP 不是指substring(0,3)吗?
        • 我冒昧地纠正了您的 (-1, 4) 错误 - 应该是 (0, 3)。干杯
        • 这个答案在编辑后似乎没有意义。
        猜你喜欢
        • 2014-12-25
        • 2016-10-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-27
        • 1970-01-01
        • 2014-12-06
        相关资源
        最近更新 更多