像Java API方法:爲什麼從索引是包含但結束索引是排他性的?
String.substring(int beginIndex, int endIndex)
String.subSequence(int beginIndex, int endIndex)
List.subList(int fromIndex, int toIndex)
爲什麼開始指數包括但最終指數獨佔?爲什麼它們不應該被設計成兼而包括?
像Java API方法:爲什麼從索引是包含但結束索引是排他性的?
String.substring(int beginIndex, int endIndex)
String.subSequence(int beginIndex, int endIndex)
List.subList(int fromIndex, int toIndex)
爲什麼開始指數包括但最終指數獨佔?爲什麼它們不應該被設計成兼而包括?
因爲:
object.length
(但對象實現此,例如,大小()等)到toIndex參數 - 無需加/減1例如:
String lastThree = str.substring(str.length() - 3, str.length());
這樣,代碼中發生了什麼非常明顯(好東西)。
EDIT C函數行爲類似這個的一個例子是strncat
從string.h
:
char *strncat(char *dest, const char *src, size_t n);
的size_t
參數的值對應於在Java endPosition
參數,因爲它們兩者的所述長度對象,但是從0開始計數,如果它們是索引,則它將是一個字節超出對象的末尾。
問題是他們沒有使用C/C++語法。 我認爲C語法更具可讀性。例如,如果你想利用與lenght 2子串從列表X的第三個元素開始,你寫
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);
其實,如果(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勝;在任何情況下都更具可讀性,可惜他們改變了這一點。但這只是一個額外的評論,你可以ingore。
這就是所謂的的Dijkstra約定範圍[i, j>
(或其他數學符號[i, j)
的。這樣你可以處理的範圍[a, b>, [b, c>, [c, d]
。
有人認爲,這是較爲有效的,而事實上我們程序員使用它:
for (int i = 0; i < n; ++i) { ... }
在這樣的範圍內的元素的數目是j - i
,所以是一個-1/+ 1保存
它也用於BitSet.set(from, to)
+1第二個原因 – 2011-06-14 04:52:34
哪個C函數這樣做? – 2011-06-14 06:31:42
不正確的是C/C++中的substr可以用作Java。 C中的substr將長度作爲第二個參數,因此substr(3,2)表示「從帶索引3的字符開始取2個字符」。 我認爲C語法更具可讀性。 – fresko 2017-11-28 11:38:04