[Java]深入底層聊ArraysList——簡單全面,深入底層的最好開始

寫博客也有一段時間了,也上過兩次推薦。但是總感覺自己的寫博客和那牛人大神的博看還有還大差距,看別人的博客時發現別人的博客的技術水平很高,但是自己去寫的時候卻很難發現那些深奧的問題。我自己反思覺得主要時因爲我開發經驗不足,遇到的問題過少所導致的。這個問題不是一天兩天能夠解決的,我只能是多閱讀牛人的博客,尋求真正的項目機會,在實戰中積累知識、發現問題。
但這並不意味着在這段時間我就放棄寫博客了。就讀者而言仔細想來這或許也不是壞事,因爲有很大的一部分讀者跟我處於差不多的水平,學完Java沒多久,想要進階Java底層的深入研究。對這部分讀者來說,看那些牛人大神的文章感覺很晦澀難懂,最終放棄。這時如果從我這種的文章入手就相對容易一點,畢竟我們有着差不多的理解深度。
廢話不說,我們今天就從源碼入手研究一下List容器吧。

  1. ArrayList
    ArrayList的底層是使用數組進行實現的
    在這裏插入圖片描述

可以看到我們向ArrayList中保存的數據都是存儲在elementData數組中的,至於這個數組爲什麼使Object類型的,爲什麼不是我們指定的泛型,建議你閱讀我的這篇博客泛型擦除
我們知道數組是有容量的,所以我們在初始化ArrayList對象使必須使用指定數組的初始容量。
在這裏插入圖片描述
使用該構造方法就可以預先指定底層數組的初始大小。從代碼可以看出,如果我們指定的數組初始大小等於0就會將數組初始化爲EMPTY_ELEMENTDATA。如果我們使用不適用該構造方法指定數組的初始容量而是使用默認的空構造器,數組就會被初始化爲DEFAULTCAPACITY_EMPTY_ELEMENTDATA。EMPTY_ELEMENTDATA、DEFAULTCAPACITY_EMPTY_ELEMENTDATA這兩個常量本質上沒什麼區別(只是被初始化爲DEFAULTCAPACITY_EMPTY_ELEMENTDATA的數組會在第一次添加數據時被擴充爲10),就是兩個空的數組。他們兩個的定義如下圖所示。
在這裏插入圖片描述
add()方法
我們都知道數組一旦確定了容量是不能改變大小的,那麼我們向ArrayList容器中添加數據時如果數組的容量不足了內部是如何處理的呢?
在這裏插入圖片描述
可以看到在添加元素之前會先進行進行容量的判定,如果容量不足就使用grow方法進行擴充。實時上確定是否擴充擴充多少的的過程是一個較爲複雜的過程我們就不將這些中間源碼展開細說(沒有太大的意思),我就簡單說一下大致過程:
第一步,要確定所需要的最小容量(minCapacity),其實就時size + 1 和10選取最大值。上來先判斷elementData是否等關於DEFAULTCAPACITY_EMPTY_ELEMENTDATA,如果等於則本次操作size + 1等於1,minCapacity取10;如果不等於minCapacity取size + 1。
第二步,判斷容量最小值minCapacit與當前數組的容量作比較,如果當前容量大,則不需要擴充。如果當前容量小則調用grow方法將容量進行擴充。
下面我們來具體看grow方法是如何擴充數組容量的。
在這裏插入圖片描述
可以看到經過一系列的if確定新的數組容量之後,調用了Arrays.copyOf()方法返回了一個新的數組。copyOf方法我們都熟,就是new 一個新的指定容量的數組,然後將原數組的數據拷貝到新的數組(至於怎麼拷貝的我不知道,因爲最終它使用的不是Java實現的該過程)。但是不管怎麼說這個過程要經歷新對象的創建,數據的轉移等過程,所付出的開銷必然不小。
get()方法
看完了add操作之後就是get()方法了,其實知道了底層是用數組實現了之後,get方法的實現也就不難想象了,就是以下標爲索引,獲取數據。沒什麼可說的。
remove方法
在這裏插入圖片描述
從源碼可以看出,也沒什麼稀奇的,就是依次遍歷數組找到要刪除的元素,然後調用fastRemove方法。
在這裏插入圖片描述
果然跟想象的一樣,該方法就是把要刪除的元素之後的元素向前移位,覆蓋要刪除的元素。只不過它用來移位的方法又是使用了非Java語言來寫(上面的add方法的實現中最終就用了這個System.arraycopy方法)。
add(int index,E elem)方法(插入元素)
此方法方法就是在指定的地方插入元素。有了上面的經驗,其實set方法的實現我們只要想象一下就可以知道。其實就是第一個add方法,和remove方法的結合而已。
在這裏插入圖片描述
。。。沒啥可說的,先保證數組容量,然後數組移位,插入新元素。

能認真看完的都是有大毅力之人。如果感覺寫的還可以的話,就來留下個贊把

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章