ArrayList部分一共五篇文章了,而且引入了時間複雜度來分析,強烈建議你們必定要按順序閱讀,本文是第2篇,相關文章分別是:面試
再次強調,ArrayList是一個普通的類,若是咱們開心,能夠本身寫一個。eclipse
ArrayList初始化 - Java那些事兒專欄 文章發表後,評論區有人問以下問題。post
咱們先回顧一下以前的所說過的數組,話很少說,上代碼:性能
老規則,咱們繼續畫一畫,加深一下印象,上圖:debug
這個圖咱們去掉了ArrayList初探 - Java那些事兒專欄 一文圖裏那些無用的細節(方法區,常量池等),方便你們看起來清晰,咱們用eclipse的debug功能看一下,看是否與咱們圖上畫的一致
3d
再看一下執行結果,也在咱們指望中。cdn
好,咱們改一下代碼,再往數組裏加添加一個叫「周八」的person對象對象
執行一下blog
看到了傳說的中數組下標越界異常。在Java中,數組一但在堆內存中建立,長度是固定的。
既然是固定的,那咱們要往數組裏加一個「周八」用戶怎麼辦?沒辦法,只能從新new長一點的新的數組,把原來數組的元素複製過去,好吧,開始寫代碼吧,相信你們都會寫
把老數組的元素循環一下,賦值給新的數組,很簡單也很清晰。debug看一下
「周八」已經有了。以上代碼雖然簡單,但還不是最優雅的,老鳥通常會這麼寫,該段代碼執行結果和上面那段代碼同樣。
再畫個圖加深一下印象吧:
此圖已用盡我洪荒之力,但願你們之後多想一想對象在堆內存中的樣子。不枉我一片苦心呀。
看到System.arraycopy()方法是否是似曾相識呢?咱們在ArrayList初探 - 知乎專欄 一文中提了一下,相信看到這裏,你們都知道ArrayList裏的底層數組擴容是怎麼實現的了吧。在ArrayList初探 - 知乎專欄 一文中,咱們知道當ArrayList若是不指定構造個數的話,第一次往裏面添加元素時底層數組會初始化一個長度爲10的數組,咱們再回顧一下昨天的源碼,再來看一下ArrayList裏的源碼,當添加第11個元素時
再看grow()方法
這兒有一段代碼:int newCapacity = oldCapacity + (oldCapacity >> 1),>>是移位運算符,至關於int newCapacity = oldCapacity + (oldCapacity/2),但性能會好一些。
本文開始那個問題,到這兒就解決了,這就是數組的擴容,通常是oldCapacity + (oldCapacity >> 1),至關於擴容1.5倍。
看到這裏,相信在之後的面試中,面試官再問數組和ArrayLIst的區別的時候,你們應該有了本身的理解,而不是去背面試題了。
ArrayList還提供了其它構造方法,咱們順便來看一下。
咱們再看一下源碼,好簡單:
當咱們在寫代碼過程當中,若是咱們大概知道元素的個數,好比一個班級大概有40-50人,咱們優先考慮List<Person> list2 = new ArrayList<>(50)以指定個數的方式去構造,這樣能夠避免底層數組的屢次拷貝,進而提升程序性能。
注:本專欄文章首發於公衆號:saysayJava。全部示例代碼均已上傳至公衆號,須要請關注下載。
若是喜歡本系列文章,請爲我點贊或順手分享,您的支持是我繼續下去的動力,您也能夠在評論區留言想了解的內容,有機會本專欄會作講解,最後別忘了關注一下我。
轉載無限歡迎,但請註明「做者」和「原文地址」。轉載請在文中保留此段,感謝您對做者版權的尊重。如需商業轉載或刊登,請聯繫做者得到受權。