ArrayList的時間複雜度 – Java那些事兒專欄

清淺池塘發表於2019-03-04

ArrayList部分一共五篇文章了,並且引入了時間複雜度來分析,強烈建議大家一定要按順序閱讀,相關文章分別是:

1、ArrayList初始化 – Java那些事兒專欄

2、ArrayList底層陣列擴容原理 – Java那些事兒專欄

3、時間複雜度 – Java那些事兒專欄

4、三顧ArrayList – Java那些事兒專欄

5、ArrayList的時間複雜度 – Java那些事兒專欄(本文)

在以前的文章裡,我們已經看過了add方法的原始碼,還有一個add方法,我們看一下, public void add(int index, E element) ,從指定位置新增元素

ArrayList的時間複雜度 – Java那些事兒專欄

按照下標把元素新增到指定位置,想必大家都知道,我們直接上原始碼。

ArrayList的時間複雜度 – Java那些事兒專欄

老規矩,我們還是畫一畫,當執行到System.arraycopy()這個方法時

ArrayList的時間複雜度 – Java那些事兒專欄

我看到有些書上寫的是依次移動元素到下一格,這種說法不夠嚴謹,所以我再強調一遍,是依次複製插入位置及後面的陣列元素,到後面一格,不是移動,因此,複製完後,arr[2],arr[3]指向對一個物件。

ArrayList的時間複雜度 – Java那些事兒專欄

在程式碼執行完這一句

ArrayList的時間複雜度 – Java那些事兒專欄

我們debug驗證一下。

ArrayList的時間複雜度 – Java那些事兒專欄

最後,在堆記憶體中建立李莫愁這個物件,把arr[2]的引用指向它。

ArrayList的時間複雜度 – Java那些事兒專欄

再debug一下

ArrayList的時間複雜度 – Java那些事兒專欄

最後我們來說說ArrayLIst這個物件裡新增的時間複雜度:

如果我們不指定位置直接新增元素時(add(E element)),元素會預設會新增在最後,不會觸發底層陣列的複製,不考慮底層陣列自動擴容的話,時間複雜度為O(1) ,在指定位置新增元素(add(int index, E element)),需要複製底層陣列,根據最壞打算時間複雜度是O(n)。

最後我們說一說讀取元素,下面程式碼是獲取List中下標為2的元素

ArrayList的時間複雜度 – Java那些事兒專欄

看一下原始碼:

ArrayList的時間複雜度 – Java那些事兒專欄

很簡單,讀取元素和陣列長度無關,直接從底層陣列裡去拿元素。

評論區有人說,為什麼是“李莫愁”,看樣子是不太喜歡“李莫愁”,我們可以呼叫 set(int index, E element)方法來替換。

ArrayList的時間複雜度 – Java那些事兒專欄

我們看一看這個方法的原始碼

ArrayList的時間複雜度 – Java那些事兒專欄

很簡單,就是往指定位置放入元素,並返回原來的元素,最後我們來畫一畫

ArrayList的時間複雜度 – Java那些事兒專欄

圖中“李莫愁”已經沒有引用指向它了,JVM會在合適的時候回收它,底層陣列第2個位置已經換成了“小龍女”,我們debug驗證一下。

ArrayList的時間複雜度 – Java那些事兒專欄

沒錯,已經換成小龍女了。

這是最後一期ArrayLIst原始碼分析,引入了時間複雜度,最後,我們來做個總結

根據前幾篇文章我們可以看出來,在ArrayList中,底層陣列存/取元素效率非常的高(get/set),時間複雜度是O(1),而查詢,插入和刪除元素效率似乎不太高,時間複雜度為O(n)。

當我們ArrayLIst裡有大量資料時,這時候去頻繁插入/刪除元素會觸發底層陣列頻繁拷貝,效率不高,還會造成記憶體空間的浪費,這個問題在另一個類:LinkedList裡有解決方案,請期待後續文章講解。

查詢元素效率不高,在HashMap裡有解決方案,請關注後續文章。

上一篇:三顧ArrayList – Java那些事兒專欄

下一篇:Arraylist與Vector的區別 – Java那些事兒專欄

注:本專欄文章首發於公眾號:saysayJava。所有示例程式碼均已上傳至公眾號,需要請關注下載。

如果喜歡本系列文章,請為我點贊或順手分享,您的支援是我繼續下去的動力,您也可以在評論區留言想了解的內容,有機會本專欄會做講解,最後別忘了關注一下我。

轉載無限歡迎,但請註明「作者」和「原文地址」。轉載請在文中保留此段,感謝您對作者版權的尊重。如需商業轉載或刊登,請聯絡作者獲得授權。

相關文章