Are the upper bounds of indexed ranges always considered exclusive?

So, in Java, when an index range is specified, the upper bound is almost always excluded.

From java.lang.String :

substring(int beginIndex, int endIndex)

Returns a new string, which is a substring of this string. The substring begins with the specified beginIndex and continues to the character in the index endIndex - 1

From java.util.Arrays :

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

from - the starting index of the range to be copied, inclusive
to - the final index of the range to be copied is exceptional.

From java.util.BitSet :

set(int fromIndex, int toIndex)

fromIndex is the index of the first bit to be set.
toIndex - index after the last set bit.

As you can see, it looks like Java is trying to make this an agreement that the upper bounds are exclusive.

My questions:

  • Is this an official official recommendation?
  • Are there any noticeable violations that we should be wary of?
  • Is there a name for this system? (ala "0-based" vs "1-based")

ACKNOWLEDGMENT: I ​​fully understand that a collection of N objects in a 0-based system is indexed 0..N-1 . My question is that if a range (2,4) , it can be either 3 or 2, depending on the system. What do you call these systems?

Again, the problem is not "first index 0 last index N-1 " vs "first index 1 last index N "; which is known as a 0-based system based on 1.

The problem is "There are 3 elements in (2,4) " and "There are 2 elements in (2,4) ." What do you call them, and one of them is officially sanctioned by the other?

+7
java collections indexing range
source share
6 answers

The credit goes to FredOverflow in its comment, saying that this is called the "half-open range." Therefore, presumably, Java Collections can be described as "0 based on half-open ranges."

I gathered some discussions about semi-open and closed ranges elsewhere:


siliconbrain.com - 16 reasons to use half-open ranges (edited for brevity):

  • The number of elements in the range [n, m) is mn (and not m-n+1 ).
  • The empty range is [n, n) (and not [n, n-1] , which can be a problem if n is an iterator already indicating the first element of the list, or if n == 0 ).
  • For float, you can write [13, 42) (instead of [13, 41.999999999999] ).
  • +1 and -1 almost never used when processing ranges. This is an advantage if they are expensive (as for dates).
  • If you write a find in a range, the fact that nothing was found can be easily indicated by returning the end as the found position: if( find( [begin, end) ) == end) nothing was found.
  • In languages ​​that start array indexes from 0 (for example, C, C ++, JAVA, NCL), the upper bound is equal to size.

Semi-outdoor and indoor ranges

Advantages of half-open ranges:

  • Empty ranges are valid: [0 .. 0]
  • It’s easy for subbands to go to the end of the original: [x .. $]
  • Easily separated ranges: [0 .. x] and [x .. $]

The advantages of closed ranges:

  • Symmetry.
  • It may be easier to read.
  • ['a' ... 'z'] does not require inconvenience + 1 after 'z' .
  • [0 ... uint.max] .

This last moment is very interesting. It is very inconvenient to write the predicate numberIsInRange(int n, int min, int max) with a half-open range if Integer.MAX_VALUE can legally be in the range.

+2
source share

In general, yes. If you work in a language with C-like syntax (C, C ++, Java), then arrays are indexed with a zero mark, and most data structures with random access (vectors, massive lists, etc.) will have zero indexes as well .

Running indexes at zero means that the size of the data structure will always be larger than the last valid index in the data structure. People often want to know the size of things, of course, and therefore it is more convenient to talk about size than to talk about the last valid index. People are used to talking about final indexing in an exclusive way, because the array a[] , which has n element long, has its last valid element in a[n-1] .

There is another advantage to using an exclusive index for the final index, which is that you can calculate the size of the sublist by subtracting the inclusive starting index from the exclusive ending index. If I call myList.sublist(3, 7) , then I get a sublist with 7 - 3 = 4 elements in it. If the sublist() method used inclusive indexes at both ends of the list, then I would need to add an extra 1 to calculate the size of the sublist.

This is especially convenient when the starting index is a variable: getting the substring myList starting with i , which is 5 elements, is just myList.sublist(i, i + 5) .

That being said, you should always read the API documentation, and not assume that a given starting index or ending index will be inclusive or exclusive. Likewise, you should document your own code to indicate whether any restrictions are included or excluded.

+5
source share

Its just from 0 to n-1 .

The list / array contains 10 elements 0-9 .

You cannot have a 0-index list that is 0-n, where cout is n, which contains an element that does not exist ...

This is a typical way of working.

+2
source share

This practice was introduced by Josh Bloch into the collections API as a contract.

After that, it became the standard in java, and when someone tried to create a public library, he assumed that he should support the contract, because users expect to see the already known behavior in the new libraries.

0
source share

Indexes in structures like these are always always based on 0. String is mainly supported by char[] . The collection structure is under the hood based on arrays, etc. This simplifies the design / support / use of the API without changing the “under the hood” method to access the required element (s) in the array.

However, there are some “exceptions,” such as setterex methods based on PreparedStatement parameters and getter methods based on ResultSet columns. They are based on 1. Behind the scenes, they also do not represent an array of values.

This will probably raise a new question: "Why are array indices based on zero?". Now our respected computer scientist EW Dijkstra here explains why it should start from scratch.

0
source share

An easy way to think about half-open ranges is this: the first term identifies the start of elements within the range, and the second term identifies the start of elements after the range. Keep that in mind and it all makes sense. Plus arithmetic works better in many cases, for @polygenelubricants answer.

0
source share

All Articles