2014-02-17 49 views
-1

主場迎戰據瞭解,如果我想找到一個對象是否是一個ArrayList我既可以使用contains()方法:的Java ArrayList包含了循環

if(arraylist.contains(obj)) { // do things } 

或者我可以用一個用於環(條件是我已重載equals()方法):

for(Object o : arraylist) { 

    if(obj.equals(o)) { 

     // do things 

    } 

} 

正如在其他職位被稱爲,含有()實際上使內部的用於循環和equals()方法。因此,我的問題是:在數組列表較大時期望contains()花費更多時間是否合乎邏輯?

我在問這是因爲在我的代碼中,我使用contains()以避免「for循環」,因此保持運行時間低且恆定,但我注意到代碼運行速度明顯慢於arraylist大小變得更大。

+2

「我注意到代碼運行作爲該ArrayList尺寸變得更大顯著慢。」,這是很有意義的,因爲更大的陣列是,則更多的元素存在通過搜索。 – Vallentin

+0

@Vallentin這也是我的想法。不過,還沒有一個性能增益(或至少不顯著之一)通過使用包含(),而不是一個手動寫的for循環,對不對? – Kotsos

+0

肯定會隨着數組列表大小的增加而變慢。 '的使用包含()'將在單行和會比你的for循環 –

回答

1

當數組列表較大時期望contains()花費更多時間是合乎邏輯的嗎?

是的。 ArrayList Javadoc說:

大小,isEmpty,get,set,iterator和listIterator操作在恆定時間內運行。 add操作以分攤的恆定時間運行,即添加n個元素需要O(n)個時間。 所有其他操作在線性時間內運行(粗略地說)

因此,的ArrayList.contains()複雜度爲爲O(n),由於需要檢查該ArrayList的每個元素這是有意義的。沒有其他的選擇,因爲一個ArrayList沒有排序,並且給定了它的值,沒有其他訪問路徑到特定的元素。

+0

「與LinkedList實現相比,常數因子較低。」這是否意味着如果我正在使用List接口的LinkedList實現而不是ArrayList,contains()方法會導致幾乎不變的時間? – Kotsos

+0

不,對於複雜性分析,*因素*並不重要。另外,它說'ArrayList'的因子較低,所以如果'ArrayList'是O(n),我希望'LinkedList'類似於O(2 * n),這會比'ArrayList'差。 –

+0

好的,謝謝你的回覆! – Kotsos

3

當arraylist較大時期望contains()花費更多時間是否合乎邏輯?

是的。通過你自己的話:

正如在其他職位被稱爲包含()實際上是利用 內部的for循環和equals()方法。

更多要搜索的元素=需要更多時間。

如果你需要不斷的查找,你可以嘗試使用一個哈希集(可能會或可能不適用於你的情況)。或者,如果您的數據已排序,則可以使用二進制搜索從O(n)到O(lg(N))。

6

是的,對於List需要與列表大小成比例的時間。如果您需要更快地檢查會員資格,請考慮使用例如HashSet,這可以在固定時間檢查會員資格。

+0

或二進制搜索 – holap

+0

一個有序的ArrayList打我一分鐘。 ;) – Bex

+0

當然,這取決於有問題的對象的位置。但是,是的,在最壞的情況下,你必須檢查所有的元素。 – Puce

1

正如很多人已經指出的那樣:是的,這是有道理的,無法避免的。

如果你想以優化包含() - 的情況下,可以考慮使用HashSet而不是ArrayList,只要你不需要拷貝,以填補集合。 HashSet搜索速度快很多。

0

的方法肯定會需要時間,因爲它是內部實現也是一個for循環,就像你給什麼作爲一個例子。

你在ArrayList它需要完成的時間越長有越多的物品。

這裏的一個類似的問題Any big difference between using contains or loop through a list?

+0

我之前看到過這個答案,但它指的是contains()與foreach | iterator案例的比較,我認爲它可能是某種不同的情況。看起來,我錯了。 – Kotsos