2016-08-15 111 views
6

ArrayList#getsetremove首先調用rangeCheck方法。此方法不檢查索引是否爲負數。它只檢查索引是否大於或等於數組的長度。 Javadoc解釋了原因;如果索引是負數,則數組訪問會拋出ArrayIndexOutOfBoundsException爲什麼ArrayList#rangeCheck不檢查索引是否爲負數?

private void rangeCheck(int index) { 
    if (index >= size) 
     throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); 
} 
public E get(int index) { 
    rangeCheck(index); 

    return elementData(index); 
} 

根據Java Langauage Specification,如果索引是不僅負而且GTE數組訪問拋出一個ArrayIndexOutOfBoundsException。

在運行時檢查所有數組訪問;嘗試使用小於零或大於或等於 數組長度的索引 會導致拋出ArrayIndexOutOfBoundsException。

我認爲rangeCheck應該同時檢查negative和gte,或者對於性能,應該不檢查。 爲什麼範圍檢查不檢查索引是否爲負值?

+4

因爲它不必。後續的數組訪問已經做到了。正如你的報價所述。 – EJP

回答

10

很簡單,因爲在ArrayList支持數組可能會大於當前大小。

在當前的實施中,每當超過當前最大容量時,ArrayList的支持陣列容量增加1.5倍。默認的初始容量爲10,當您嘗試將第11個元素添加到列表中時,陣列會被重新分配容量爲15.當您超過15時,它將變爲22等。

在任何給定時間,容量可能大於ArrayList中當前元素的數量。

檢查負索引是留給JVM(在後備陣列上),並且ArrayList本身只需檢查當前列表的上端。

+0

['增長策略的詳細信息除了添加一個元素具有不變的分攤時間成本之外沒有指定'](https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList的.html)。 – EJP

+0

不,你不是。你正在描述'Vector'。 ArrayList的當前實現增長了1.5倍。 – EJP

+0

你是對的,從我看grepcode已經有一段時間了。或者,我可能會把它與'HashMap'中桶數組的增量混淆起來。再次編輯。 –

相關問題